mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-03 08:02:14 +02:00
Compare commits
11 Commits
826c3fec47
...
9b480e4757
Author | SHA1 | Date | |
---|---|---|---|
|
9b480e4757 | ||
|
e1c4523c41 | ||
|
85c23b5781 | ||
|
8e042f2262 | ||
|
81e9154a52 | ||
|
e9b9dbc2aa | ||
|
7e6c849ca4 | ||
|
8ec7c096d0 | ||
|
6e5b901a9b | ||
|
b800953d66 | ||
|
f0240db75a |
@ -1,4 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 1.5.3
|
||||||
|
+ Support was added for 16.0.3.
|
||||||
|
+ Atmosphère was updated to use GCC 13/newlib (latest devkitA64/devkitARM releases).
|
||||||
|
+ **Please note**: This introduces a known issue, which is currently being worked on.
|
||||||
|
+ As you may recall from the 1.4.1 changelog, Fire Emblem: Engage requires enormous amounts of memory to support using layeredfs mods with the game.
|
||||||
|
+ Latest GCC/newlib slightly increases malloc overhead size, which makes the previous memory increase insufficient.
|
||||||
|
+ A general-case solution to this is in the works, which should hopefully fix the problem in a way that doesn't jinx me for the future.
|
||||||
|
+ A number of minor issues were fixed and improvements were made, including:
|
||||||
|
+ An issue was fixed that caused system font replacement to not work on 16.0.0+.
|
||||||
|
+ An minor accuracy issue was addressed in mesosphere's management of certain memory ranges; this issue would have had zero visible impact to the end-user.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 1.5.2
|
## 1.5.2
|
||||||
+ A homebrew application (`haze`) was added for performing USB file transfer (with thanks to @liamwhite for both design and implementation).
|
+ A homebrew application (`haze`) was added for performing USB file transfer (with thanks to @liamwhite for both design and implementation).
|
||||||
+ `haze` is included with atmosphère, and provides access to the SD card via the PTP/MTP protocol.
|
+ `haze` is included with atmosphère, and provides access to the SD card via the PTP/MTP protocol.
|
||||||
|
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emummc
|
remote = https://github.com/m4xw/emummc
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = bba1f1fb65f75721caf6d023a35d75d3c9aafd0f
|
commit = 30205111ee375bef96f0f76cb6a3130a2f0fc85c
|
||||||
parent = 1ab8b234447864503e21c600681219a96962e6c1
|
parent = 81e9154a52a976f85317bddd0131426599d26a62
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@ -2,7 +2,7 @@
|
|||||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||||
|
|
||||||
### Supported Horizon Versions
|
### Supported Horizon Versions
|
||||||
**1.0.0 - 16.0.0**
|
**1.0.0 - 16.0.3**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Arbitrary SDMMC backend selection
|
* Arbitrary SDMMC backend selection
|
||||||
|
8
emummc/source/FS/FS_offsets.c
vendored
8
emummc/source/FS/FS_offsets.c
vendored
@ -65,6 +65,8 @@
|
|||||||
#include "offsets/1500_exfat.h"
|
#include "offsets/1500_exfat.h"
|
||||||
#include "offsets/1600.h"
|
#include "offsets/1600.h"
|
||||||
#include "offsets/1600_exfat.h"
|
#include "offsets/1600_exfat.h"
|
||||||
|
#include "offsets/1603.h"
|
||||||
|
#include "offsets/1603_exfat.h"
|
||||||
#include "../utils/fatal.h"
|
#include "../utils/fatal.h"
|
||||||
|
|
||||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||||
@ -141,6 +143,8 @@ DEFINE_OFFSET_STRUCT(_1500);
|
|||||||
DEFINE_OFFSET_STRUCT(_1500_EXFAT);
|
DEFINE_OFFSET_STRUCT(_1500_EXFAT);
|
||||||
DEFINE_OFFSET_STRUCT(_1600);
|
DEFINE_OFFSET_STRUCT(_1600);
|
||||||
DEFINE_OFFSET_STRUCT(_1600_EXFAT);
|
DEFINE_OFFSET_STRUCT(_1600_EXFAT);
|
||||||
|
DEFINE_OFFSET_STRUCT(_1603);
|
||||||
|
DEFINE_OFFSET_STRUCT(_1603_EXFAT);
|
||||||
|
|
||||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
@ -242,6 +246,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
|||||||
return &(GET_OFFSET_STRUCT_NAME(_1600));
|
return &(GET_OFFSET_STRUCT_NAME(_1600));
|
||||||
case FS_VER_16_0_0_EXFAT:
|
case FS_VER_16_0_0_EXFAT:
|
||||||
return &(GET_OFFSET_STRUCT_NAME(_1600_EXFAT));
|
return &(GET_OFFSET_STRUCT_NAME(_1600_EXFAT));
|
||||||
|
case FS_VER_16_0_3:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_1603));
|
||||||
|
case FS_VER_16_0_3_EXFAT:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_1603_EXFAT));
|
||||||
default:
|
default:
|
||||||
fatal_abort(Fatal_UnknownVersion);
|
fatal_abort(Fatal_UnknownVersion);
|
||||||
}
|
}
|
||||||
|
3
emummc/source/FS/FS_versions.h
vendored
3
emummc/source/FS/FS_versions.h
vendored
@ -95,6 +95,9 @@ enum FS_VER
|
|||||||
FS_VER_16_0_0,
|
FS_VER_16_0_0,
|
||||||
FS_VER_16_0_0_EXFAT,
|
FS_VER_16_0_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_16_0_3,
|
||||||
|
FS_VER_16_0_3_EXFAT,
|
||||||
|
|
||||||
FS_VER_MAX,
|
FS_VER_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
59
emummc/source/FS/offsets/1603.h
vendored
Normal file
59
emummc/source/FS/offsets/1603.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_1603_H__
|
||||||
|
#define __FS_1603_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_1603_SDMMC_ACCESSOR_GC 0x1862F0
|
||||||
|
#define FS_OFFSET_1603_SDMMC_ACCESSOR_SD 0x187F70
|
||||||
|
#define FS_OFFSET_1603_SDMMC_ACCESSOR_NAND 0x1867B0
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_1603_SDMMC_WRAPPER_READ 0x182240
|
||||||
|
#define FS_OFFSET_1603_SDMMC_WRAPPER_WRITE 0x1822A0
|
||||||
|
#define FS_OFFSET_1603_RTLD 0x269B0
|
||||||
|
#define FS_OFFSET_1603_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||||
|
|
||||||
|
#define FS_OFFSET_1603_CLKRST_SET_MIN_V_CLK_RATE 0x1A2D80
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_1603_LOCK_MUTEX 0x17B780
|
||||||
|
#define FS_OFFSET_1603_UNLOCK_MUTEX 0x17B7D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_1603_SDMMC_WRAPPER_CONTROLLER_OPEN 0x182200
|
||||||
|
#define FS_OFFSET_1603_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x182220
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_1603_SD_MUTEX 0xFFB3F0
|
||||||
|
#define FS_OFFSET_1603_NAND_MUTEX 0xFF6B58
|
||||||
|
#define FS_OFFSET_1603_ACTIVE_PARTITION 0xFF6B98
|
||||||
|
#define FS_OFFSET_1603_SDMMC_DAS_HANDLE 0xFDC8B0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_1603_SD_DAS_INIT 0x258D4
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_1603_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00063B98, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070DBC, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0007795C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008A7A4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_1603_H__
|
59
emummc/source/FS/offsets/1603_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1603_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_1603_EXFAT_H__
|
||||||
|
#define __FS_1603_EXFAT_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_GC 0x190FD0
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_SD 0x192C50
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_NAND 0x191490
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_READ 0x18CF20
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_WRITE 0x18CF80
|
||||||
|
#define FS_OFFSET_1603_EXFAT_RTLD 0x269B0
|
||||||
|
#define FS_OFFSET_1603_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||||
|
|
||||||
|
#define FS_OFFSET_1603_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1ADA60
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_1603_EXFAT_LOCK_MUTEX 0x186460
|
||||||
|
#define FS_OFFSET_1603_EXFAT_UNLOCK_MUTEX 0x1864B0
|
||||||
|
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x18CEE0
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x18CF00
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SD_MUTEX 0x100D3F0
|
||||||
|
#define FS_OFFSET_1603_EXFAT_NAND_MUTEX 0x1008B58
|
||||||
|
#define FS_OFFSET_1603_EXFAT_ACTIVE_PARTITION 0x1008B98
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SDMMC_DAS_HANDLE 0xFE98B0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_1603_EXFAT_SD_DAS_INIT 0x258D4
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_1603_EXFAT_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00063B98, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070DBC, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0007795C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008A7A4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_1603_EXFAT_H__
|
@ -162,6 +162,9 @@ namespace ams::nxboot {
|
|||||||
FsVersion_16_0_0,
|
FsVersion_16_0_0,
|
||||||
FsVersion_16_0_0_Exfat,
|
FsVersion_16_0_0_Exfat,
|
||||||
|
|
||||||
|
FsVersion_16_0_3,
|
||||||
|
FsVersion_16_0_3_Exfat,
|
||||||
|
|
||||||
FsVersion_Count,
|
FsVersion_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -239,6 +242,9 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
{ 0x56, 0xE8, 0x56, 0x56, 0x6C, 0x38, 0xD8, 0xBE }, /* FsVersion_16_0_0 */
|
{ 0x56, 0xE8, 0x56, 0x56, 0x6C, 0x38, 0xD8, 0xBE }, /* FsVersion_16_0_0 */
|
||||||
{ 0xCF, 0xAB, 0x45, 0x0C, 0x2C, 0x53, 0x9D, 0xA9 }, /* FsVersion_16_0_0_Exfat */
|
{ 0xCF, 0xAB, 0x45, 0x0C, 0x2C, 0x53, 0x9D, 0xA9 }, /* FsVersion_16_0_0_Exfat */
|
||||||
|
|
||||||
|
{ 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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||||
@ -656,6 +662,14 @@ namespace ams::nxboot {
|
|||||||
AddPatch(fs_meta, 0x1913B9, NogcPatch0, sizeof(NogcPatch0));
|
AddPatch(fs_meta, 0x1913B9, NogcPatch0, sizeof(NogcPatch0));
|
||||||
AddPatch(fs_meta, 0x16B950, NogcPatch1, sizeof(NogcPatch1));
|
AddPatch(fs_meta, 0x16B950, NogcPatch1, sizeof(NogcPatch1));
|
||||||
break;
|
break;
|
||||||
|
case FsVersion_16_0_3:
|
||||||
|
AddPatch(fs_meta, 0x186729, NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x160CC0, NogcPatch1, sizeof(NogcPatch1));
|
||||||
|
break;
|
||||||
|
case FsVersion_16_0_3_Exfat:
|
||||||
|
AddPatch(fs_meta, 0x191409, NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x16B9A0, NogcPatch1, sizeof(NogcPatch1));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = ecc8b18111730acef0a353f6f61c45c1f143a793
|
commit = cd0fc2c1d5728ec45414aaaa6efa28c269695992
|
||||||
parent = d8aed7de6d39dd29b75e34f24d376decfb77a5b4
|
parent = 8ec7c096d04e6f9586be2cb785840cd482d4b900
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
@ -78,6 +78,7 @@ namespace ams::hos {
|
|||||||
Version_16_0_0 = ::ams::TargetFirmware_16_0_0,
|
Version_16_0_0 = ::ams::TargetFirmware_16_0_0,
|
||||||
Version_16_0_1 = ::ams::TargetFirmware_16_0_1,
|
Version_16_0_1 = ::ams::TargetFirmware_16_0_1,
|
||||||
Version_16_0_2 = ::ams::TargetFirmware_16_0_2,
|
Version_16_0_2 = ::ams::TargetFirmware_16_0_2,
|
||||||
|
Version_16_0_3 = ::ams::TargetFirmware_16_0_3,
|
||||||
|
|
||||||
Version_Current = ::ams::TargetFirmware_Current,
|
Version_Current = ::ams::TargetFirmware_Current,
|
||||||
|
|
||||||
|
@ -19,31 +19,34 @@
|
|||||||
#include <stratosphere/pm/pm_types.hpp>
|
#include <stratosphere/pm/pm_types.hpp>
|
||||||
#include <stratosphere/sf.hpp>
|
#include <stratosphere/sf.hpp>
|
||||||
|
|
||||||
#define AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \
|
#define AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \
|
AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \
|
AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \
|
AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out<pm::ProcessEventInfo> out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out<pm::ProcessEventInfo> out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 5, void, NotifyBootFinished, (), ()) \
|
AMS_SF_METHOD_INFO(C, H, 5, void, NotifyBootFinished, (), ()) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 6, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 6, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \
|
AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 8, Result, BoostApplicationThreadResourceLimit, (), ()) \
|
AMS_SF_METHOD_INFO(C, H, 8, Result, BoostApplicationThreadResourceLimit, (), ()) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 9, void, GetBootFinishedEventHandle, (sf::OutCopyHandle out), (out), hos::Version_8_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 9, void, GetBootFinishedEventHandle, (sf::OutCopyHandle out), (out), hos::Version_8_0_0) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ())
|
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereBoostSystemMemoryResourceLimitForMitm, (u64 boost_size), (boost_size))
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
||||||
|
|
||||||
#define AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO(C, H) \
|
#define AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \
|
AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \
|
AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \
|
AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out<pm::ProcessEventInfo> out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out<pm::ProcessEventInfo> out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 5, Result, CleanupProcess, (os::ProcessId process_id), (process_id)) \
|
AMS_SF_METHOD_INFO(C, H, 5, Result, CleanupProcess, (os::ProcessId process_id), (process_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 6, Result, ClearExceptionOccurred, (os::ProcessId process_id), (process_id)) \
|
AMS_SF_METHOD_INFO(C, H, 6, Result, ClearExceptionOccurred, (os::ProcessId process_id), (process_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 7, void, NotifyBootFinished, (), ()) \
|
AMS_SF_METHOD_INFO(C, H, 7, void, NotifyBootFinished, (), ()) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 9, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size), hos::Version_4_0_0)
|
AMS_SF_METHOD_INFO(C, H, 9, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size), hos::Version_4_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereBoostSystemMemoryResourceLimitForMitm, (u64 boost_size), (boost_size))
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
||||||
|
@ -32,4 +32,6 @@ namespace ams::pm::shell {
|
|||||||
Result BoostApplicationThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostSystemThreadResourceLimit();
|
||||||
|
|
||||||
|
Result AtmosphereBoostSystemMemoryResourceLimitForMitm(u64 size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,3 +90,9 @@ Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result pmshellAtmosphereBoostSystemMemoryResourceLimitForMitm(u64 size) {
|
||||||
|
return serviceDispatchIn(pmshellGetServiceSession(), 65000, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideSt
|
|||||||
Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid);
|
Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid);
|
||||||
Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group, u32 resource);
|
Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group, u32 resource);
|
||||||
|
|
||||||
|
Result pmshellAtmosphereBoostSystemMemoryResourceLimitForMitm(u64 size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include "pm_ams.os.horizon.h"
|
||||||
|
|
||||||
namespace ams::pm::shell {
|
namespace ams::pm::shell {
|
||||||
|
|
||||||
@ -57,6 +58,10 @@ namespace ams::pm::shell {
|
|||||||
Result BoostSystemThreadResourceLimit() {
|
Result BoostSystemThreadResourceLimit() {
|
||||||
R_RETURN(::pmshellBoostSystemThreadResourceLimit());
|
R_RETURN(::pmshellBoostSystemThreadResourceLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result AtmosphereBoostSystemMemoryResourceLimitForMitm(u64 size) {
|
||||||
|
R_RETURN(pmshellAtmosphereBoostSystemMemoryResourceLimitForMitm(size));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
|
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 5
|
#define ATMOSPHERE_RELEASE_VERSION_MINOR 5
|
||||||
#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_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_MAJOR 16
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 2
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 3
|
||||||
|
@ -76,8 +76,9 @@
|
|||||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_0 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_0 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 0)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_1 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 1)
|
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_1 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 1)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_2 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 2)
|
#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_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_0_2
|
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_0_3
|
||||||
|
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||||
@ -146,6 +147,7 @@ namespace ams {
|
|||||||
TargetFirmware_16_0_0 = ATMOSPHERE_TARGET_FIRMWARE_16_0_0,
|
TargetFirmware_16_0_0 = ATMOSPHERE_TARGET_FIRMWARE_16_0_0,
|
||||||
TargetFirmware_16_0_1 = ATMOSPHERE_TARGET_FIRMWARE_16_0_1,
|
TargetFirmware_16_0_1 = ATMOSPHERE_TARGET_FIRMWARE_16_0_1,
|
||||||
TargetFirmware_16_0_2 = ATMOSPHERE_TARGET_FIRMWARE_16_0_2,
|
TargetFirmware_16_0_2 = ATMOSPHERE_TARGET_FIRMWARE_16_0_2,
|
||||||
|
TargetFirmware_16_0_3 = ATMOSPHERE_TARGET_FIRMWARE_16_0_3,
|
||||||
|
|
||||||
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ namespace ams::mitm::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We want to mitm sdb, to support sd-romfs redirection of common system archives (like system font, etc). */
|
/* We want to mitm sdb, to support sd-romfs redirection of common system archives (like system font, etc). */
|
||||||
if (program_id == ncm::SystemProgramId::Sdb) {
|
/* NOTE: In 16.0.0+, this was moved to glue. */
|
||||||
|
if (program_id == ncm::SystemProgramId::Sdb || program_id == ncm::SystemProgramId::Glue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace ams::mitm::fs {
|
|||||||
|
|
||||||
class LayeredRomfsStorageImpl {
|
class LayeredRomfsStorageImpl {
|
||||||
private:
|
private:
|
||||||
std::vector<romfs::SourceInfo> m_source_infos;
|
romfs::Builder::SourceInfoVector m_source_infos;
|
||||||
std::unique_ptr<ams::fs::IStorage> m_storage_romfs;
|
std::unique_ptr<ams::fs::IStorage> m_storage_romfs;
|
||||||
std::unique_ptr<ams::fs::IStorage> m_file_romfs;
|
std::unique_ptr<ams::fs::IStorage> m_file_romfs;
|
||||||
os::Event m_initialize_event;
|
os::Event m_initialize_event;
|
||||||
|
@ -23,6 +23,27 @@ namespace ams::mitm::fs {
|
|||||||
|
|
||||||
namespace romfs {
|
namespace romfs {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/* TODO: Fancy Dynamic allocation globals. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void *AllocateTracked(AllocationType type, size_t size) {
|
||||||
|
AMS_UNUSED(type);
|
||||||
|
|
||||||
|
/* TODO: Fancy dynamic allocation with memory stealing from application pool. */
|
||||||
|
return std::malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeTracked(AllocationType type, void *p, size_t size) {
|
||||||
|
AMS_UNUSED(type);
|
||||||
|
AMS_UNUSED(size);
|
||||||
|
|
||||||
|
/* TODO: Fancy dynamic allocation with memory stealing from application pool. */
|
||||||
|
return std::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr u32 EmptyEntry = 0xFFFFFFFF;
|
constexpr u32 EmptyEntry = 0xFFFFFFFF;
|
||||||
@ -71,22 +92,23 @@ namespace ams::mitm::fs {
|
|||||||
static constexpr size_t MaxCachedSize = (1_MB / 4);
|
static constexpr size_t MaxCachedSize = (1_MB / 4);
|
||||||
private:
|
private:
|
||||||
size_t m_cache_bitsize;
|
size_t m_cache_bitsize;
|
||||||
|
size_t m_cache_size;
|
||||||
protected:
|
protected:
|
||||||
void *m_cache;
|
void *m_cache;
|
||||||
protected:
|
protected:
|
||||||
DynamicTableCache(size_t sz) {
|
DynamicTableCache(size_t sz) {
|
||||||
size_t cache_size = util::CeilingPowerOfTwo(std::min(sz, MaxCachedSize));
|
m_cache_size = util::CeilingPowerOfTwo(std::min(sz, MaxCachedSize));
|
||||||
m_cache = std::malloc(cache_size);
|
m_cache = AllocateTracked(AllocationType_TableCache, m_cache_size);
|
||||||
while (m_cache == nullptr) {
|
while (m_cache == nullptr) {
|
||||||
cache_size >>= 1;
|
m_cache_size >>= 1;
|
||||||
AMS_ABORT_UNLESS(cache_size >= 16_KB);
|
AMS_ABORT_UNLESS(m_cache_size >= 16_KB);
|
||||||
m_cache = std::malloc(cache_size);
|
m_cache = AllocateTracked(AllocationType_TableCache, m_cache_size);
|
||||||
}
|
}
|
||||||
m_cache_bitsize = util::CountTrailingZeros(cache_size);
|
m_cache_bitsize = util::CountTrailingZeros(m_cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DynamicTableCache() {
|
~DynamicTableCache() {
|
||||||
std::free(m_cache);
|
FreeTracked(AllocationType_TableCache, m_cache, m_cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE size_t GetCacheSize() const { return static_cast<size_t>(1) << m_cache_bitsize; }
|
ALWAYS_INLINE size_t GetCacheSize() const { return static_cast<size_t>(1) << m_cache_bitsize; }
|
||||||
@ -293,7 +315,7 @@ namespace ams::mitm::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Builder::Builder(ncm::ProgramId pr_id) : m_program_id(pr_id), m_num_dirs(0), m_num_files(0), m_dir_table_size(0), m_file_table_size(0), m_dir_hash_table_size(0), m_file_hash_table_size(0), m_file_partition_size(0) {
|
Builder::Builder(ncm::ProgramId pr_id) : m_program_id(pr_id), m_num_dirs(0), m_num_files(0), m_dir_table_size(0), m_file_table_size(0), m_dir_hash_table_size(0), m_file_hash_table_size(0), m_file_partition_size(0) {
|
||||||
auto res = m_directories.emplace(std::make_unique<BuildDirectoryContext>(BuildDirectoryContext::RootTag{}));
|
auto res = m_directories.emplace(std::unique_ptr<BuildDirectoryContext>(AllocateTyped<BuildDirectoryContext>(AllocationType_BuildDirContext, BuildDirectoryContext::RootTag{})));
|
||||||
AMS_ABORT_UNLESS(res.second);
|
AMS_ABORT_UNLESS(res.second);
|
||||||
m_root = res.first->get();
|
m_root = res.first->get();
|
||||||
m_num_dirs = 1;
|
m_num_dirs = 1;
|
||||||
@ -347,9 +369,9 @@ namespace ams::mitm::fs {
|
|||||||
AMS_ABORT_UNLESS(num_child_dirs >= 0);
|
AMS_ABORT_UNLESS(num_child_dirs >= 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
BuildDirectoryContext **child_dirs = num_child_dirs != 0 ? reinterpret_cast<BuildDirectoryContext **>(std::malloc(sizeof(BuildDirectoryContext *) * num_child_dirs)) : nullptr;
|
BuildDirectoryContext **child_dirs = num_child_dirs != 0 ? reinterpret_cast<BuildDirectoryContext **>(AllocateTracked(AllocationType_DirPointerArray, sizeof(BuildDirectoryContext *) * num_child_dirs)) : nullptr;
|
||||||
AMS_ABORT_UNLESS(num_child_dirs == 0 || child_dirs != nullptr);
|
AMS_ABORT_UNLESS(num_child_dirs == 0 || child_dirs != nullptr);
|
||||||
ON_SCOPE_EXIT { std::free(child_dirs); };
|
ON_SCOPE_EXIT { if (child_dirs != nullptr) { FreeTracked(AllocationType_DirPointerArray, child_dirs, sizeof(BuildDirectoryContext *) * num_child_dirs); } };
|
||||||
|
|
||||||
s64 cur_child_dir_ind = 0;
|
s64 cur_child_dir_ind = 0;
|
||||||
{
|
{
|
||||||
@ -368,12 +390,12 @@ namespace ams::mitm::fs {
|
|||||||
AMS_ABORT_UNLESS(child_dirs != nullptr);
|
AMS_ABORT_UNLESS(child_dirs != nullptr);
|
||||||
|
|
||||||
BuildDirectoryContext *real_child = nullptr;
|
BuildDirectoryContext *real_child = nullptr;
|
||||||
this->AddDirectory(std::addressof(real_child), parent, std::make_unique<BuildDirectoryContext>(m_dir_entry.name, strlen(m_dir_entry.name)));
|
this->AddDirectory(std::addressof(real_child), parent, std::unique_ptr<BuildDirectoryContext>(AllocateTyped<BuildDirectoryContext>(AllocationType_BuildDirContext, m_dir_entry.name, strlen(m_dir_entry.name))));
|
||||||
AMS_ABORT_UNLESS(real_child != nullptr);
|
AMS_ABORT_UNLESS(real_child != nullptr);
|
||||||
child_dirs[cur_child_dir_ind++] = real_child;
|
child_dirs[cur_child_dir_ind++] = real_child;
|
||||||
AMS_ABORT_UNLESS(cur_child_dir_ind <= num_child_dirs);
|
AMS_ABORT_UNLESS(cur_child_dir_ind <= num_child_dirs);
|
||||||
} else /* if (m_dir_entry.type == FsDirEntryType_File) */ {
|
} else /* if (m_dir_entry.type == FsDirEntryType_File) */ {
|
||||||
this->AddFile(parent, std::make_unique<BuildFileContext>(m_dir_entry.name, strlen(m_dir_entry.name), m_dir_entry.file_size, 0, m_cur_source_type));
|
this->AddFile(parent, std::unique_ptr<BuildFileContext>(AllocateTyped<BuildFileContext>(AllocationType_BuildFileContext, m_dir_entry.name, strlen(m_dir_entry.name), m_dir_entry.file_size, 0, m_cur_source_type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,7 +425,7 @@ namespace ams::mitm::fs {
|
|||||||
while (cur_file_offset != EmptyEntry) {
|
while (cur_file_offset != EmptyEntry) {
|
||||||
const FileEntry *cur_file = file_table.GetEntry(cur_file_offset);
|
const FileEntry *cur_file = file_table.GetEntry(cur_file_offset);
|
||||||
|
|
||||||
this->AddFile(parent, std::make_unique<BuildFileContext>(cur_file->name, cur_file->name_size, cur_file->size, cur_file->offset, m_cur_source_type));
|
this->AddFile(parent, std::unique_ptr<BuildFileContext>(AllocateTyped<BuildFileContext>(AllocationType_BuildFileContext, cur_file->name, cur_file->name_size, cur_file->size, cur_file->offset, m_cur_source_type)));
|
||||||
|
|
||||||
cur_file_offset = cur_file->sibling;
|
cur_file_offset = cur_file->sibling;
|
||||||
}
|
}
|
||||||
@ -415,7 +437,7 @@ namespace ams::mitm::fs {
|
|||||||
{
|
{
|
||||||
const DirectoryEntry *cur_child = dir_table.GetEntry(cur_child_offset);
|
const DirectoryEntry *cur_child = dir_table.GetEntry(cur_child_offset);
|
||||||
|
|
||||||
this->AddDirectory(std::addressof(real_child), parent, std::make_unique<BuildDirectoryContext>(cur_child->name, cur_child->name_size));
|
this->AddDirectory(std::addressof(real_child), parent, std::unique_ptr<BuildDirectoryContext>(AllocateTyped<BuildDirectoryContext>(AllocationType_BuildDirContext, cur_child->name, cur_child->name_size)));
|
||||||
AMS_ABORT_UNLESS(real_child != nullptr);
|
AMS_ABORT_UNLESS(real_child != nullptr);
|
||||||
|
|
||||||
next_child_offset = cur_child->sibling;
|
next_child_offset = cur_child->sibling;
|
||||||
@ -438,7 +460,7 @@ namespace ams::mitm::fs {
|
|||||||
/* If there is no romfs folder on the SD, don't bother continuing. */
|
/* If there is no romfs folder on the SD, don't bother continuing. */
|
||||||
{
|
{
|
||||||
FsDir dir;
|
FsDir dir;
|
||||||
if (R_FAILED(mitm::fs::OpenAtmosphereRomfsDirectory(std::addressof(dir), m_program_id, m_root->path.get(), OpenDirectoryMode_Directory, std::addressof(sd_filesystem)))) {
|
if (R_FAILED(mitm::fs::OpenAtmosphereRomfsDirectory(std::addressof(dir), m_program_id, m_root->path, OpenDirectoryMode_Directory, std::addressof(sd_filesystem)))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fsDirClose(std::addressof(dir));
|
fsDirClose(std::addressof(dir));
|
||||||
@ -461,7 +483,7 @@ namespace ams::mitm::fs {
|
|||||||
this->VisitDirectory(m_root, 0x0, dir_table, file_table);
|
this->VisitDirectory(m_root, 0x0, dir_table, file_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::Build(std::vector<SourceInfo> *out_infos) {
|
void Builder::Build(SourceInfoVector *out_infos) {
|
||||||
/* Clear output. */
|
/* Clear output. */
|
||||||
out_infos->clear();
|
out_infos->clear();
|
||||||
|
|
||||||
@ -477,7 +499,7 @@ namespace ams::mitm::fs {
|
|||||||
m_file_hash_table_size = sizeof(u32) * num_file_hash_table_entries;
|
m_file_hash_table_size = sizeof(u32) * num_file_hash_table_entries;
|
||||||
|
|
||||||
/* Allocate metadata, make pointers. */
|
/* Allocate metadata, make pointers. */
|
||||||
Header *header = reinterpret_cast<Header *>(std::malloc(sizeof(Header)));
|
Header *header = reinterpret_cast<Header *>(AllocateTracked(AllocationType_Memory, sizeof(Header)));
|
||||||
std::memset(header, 0x00, sizeof(*header));
|
std::memset(header, 0x00, sizeof(*header));
|
||||||
|
|
||||||
/* Open metadata file. */
|
/* Open metadata file. */
|
||||||
@ -552,13 +574,13 @@ namespace ams::mitm::fs {
|
|||||||
/* Set all files' hash value = hash index. */
|
/* Set all files' hash value = hash index. */
|
||||||
for (const auto &it : m_files) {
|
for (const auto &it : m_files) {
|
||||||
BuildFileContext *cur_file = it.get();
|
BuildFileContext *cur_file = it.get();
|
||||||
cur_file->hash_value = CalculatePathHash(cur_file->parent->entry_offset, cur_file->path.get(), 0, cur_file->path_len) % num_file_hash_table_entries;
|
cur_file->hash_value = CalculatePathHash(cur_file->parent->entry_offset, cur_file->path, 0, cur_file->path_len) % num_file_hash_table_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set all directories' hash value = hash index. */
|
/* Set all directories' hash value = hash index. */
|
||||||
for (const auto &it : m_directories) {
|
for (const auto &it : m_directories) {
|
||||||
BuildDirectoryContext *cur_dir = it.get();
|
BuildDirectoryContext *cur_dir = it.get();
|
||||||
cur_dir->hash_value = CalculatePathHash(cur_dir == m_root ? 0 : cur_dir->parent->entry_offset, cur_dir->path.get(), 0, cur_dir->path_len) % num_dir_hash_table_entries;
|
cur_dir->hash_value = CalculatePathHash(cur_dir == m_root ? 0 : cur_dir->parent->entry_offset, cur_dir->path, 0, cur_dir->path_len) % num_dir_hash_table_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write hash tables. */
|
/* Write hash tables. */
|
||||||
@ -661,7 +683,7 @@ namespace ams::mitm::fs {
|
|||||||
const u32 name_size = cur_file->path_len;
|
const u32 name_size = cur_file->path_len;
|
||||||
cur_entry->name_size = name_size;
|
cur_entry->name_size = name_size;
|
||||||
if (name_size) {
|
if (name_size) {
|
||||||
std::memcpy(cur_entry->name, cur_file->path.get(), name_size);
|
std::memcpy(cur_entry->name, cur_file->path, name_size);
|
||||||
for (size_t i = name_size; i < util::AlignUp(name_size, 4); i++) {
|
for (size_t i = name_size; i < util::AlignUp(name_size, 4); i++) {
|
||||||
cur_entry->name[i] = 0;
|
cur_entry->name[i] = 0;
|
||||||
}
|
}
|
||||||
@ -688,9 +710,10 @@ namespace ams::mitm::fs {
|
|||||||
AMS_ABORT_UNLESS(path_needed_size <= sizeof(full_path));
|
AMS_ABORT_UNLESS(path_needed_size <= sizeof(full_path));
|
||||||
cur_file->GetPath(full_path);
|
cur_file->GetPath(full_path);
|
||||||
|
|
||||||
cur_file->path.reset();
|
FreeTracked(AllocationType_FileName, cur_file->path, cur_file->path_len + 1);
|
||||||
|
cur_file->path = nullptr;
|
||||||
|
|
||||||
char *new_path = new char[path_needed_size];
|
char *new_path = static_cast<char *>(AllocateTracked(AllocationType_FullPath, path_needed_size));
|
||||||
std::memcpy(new_path, full_path, path_needed_size);
|
std::memcpy(new_path, full_path, path_needed_size);
|
||||||
out_infos->emplace_back(cur_file->offset + FilePartitionOffset, cur_file->size, cur_file->source_type, new_path);
|
out_infos->emplace_back(cur_file->offset + FilePartitionOffset, cur_file->size, cur_file->source_type, new_path);
|
||||||
}
|
}
|
||||||
@ -719,7 +742,7 @@ namespace ams::mitm::fs {
|
|||||||
const u32 name_size = cur_dir->path_len;
|
const u32 name_size = cur_dir->path_len;
|
||||||
cur_entry->name_size = name_size;
|
cur_entry->name_size = name_size;
|
||||||
if (name_size) {
|
if (name_size) {
|
||||||
std::memcpy(cur_entry->name, cur_dir->path.get(), name_size);
|
std::memcpy(cur_entry->name, cur_dir->path, name_size);
|
||||||
for (size_t i = name_size; i < util::AlignUp(name_size, 4); i++) {
|
for (size_t i = name_size; i < util::AlignUp(name_size, 4); i++) {
|
||||||
cur_entry->name[i] = 0;
|
cur_entry->name[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,52 @@ namespace ams::mitm::fs::romfs {
|
|||||||
Memory,
|
Memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AllocationType {
|
||||||
|
AllocationType_FileName,
|
||||||
|
AllocationType_DirName,
|
||||||
|
AllocationType_FullPath,
|
||||||
|
AllocationType_SourceInfo,
|
||||||
|
AllocationType_BuildFileContext,
|
||||||
|
AllocationType_BuildDirContext,
|
||||||
|
AllocationType_TableCache,
|
||||||
|
AllocationType_DirPointerArray,
|
||||||
|
AllocationType_DirContextSet,
|
||||||
|
AllocationType_FileContextSet,
|
||||||
|
AllocationType_Memory,
|
||||||
|
|
||||||
|
AllocationType_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
void *AllocateTracked(AllocationType type, size_t size);
|
||||||
|
void FreeTracked(AllocationType type, void *p, size_t size);
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
T *AllocateTyped(AllocationType type, Args &&... args) {
|
||||||
|
void *mem = AllocateTracked(type, sizeof(T));
|
||||||
|
return std::construct_at(static_cast<T *>(mem), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AllocationType AllocType, typename T>
|
||||||
|
class TrackedAllocator {
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
using other = TrackedAllocator<AllocType, U>;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
TrackedAllocator() = default;
|
||||||
|
|
||||||
|
T *allocate(size_t n) {
|
||||||
|
return static_cast<T *>(AllocateTracked(AllocType, sizeof(T) * n));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T *p, size_t n) {
|
||||||
|
FreeTracked(AllocType, p, sizeof(T) * n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct SourceInfo {
|
struct SourceInfo {
|
||||||
s64 virtual_offset;
|
s64 virtual_offset;
|
||||||
s64 size;
|
s64 size;
|
||||||
@ -89,10 +135,10 @@ namespace ams::mitm::fs::romfs {
|
|||||||
delete this->metadata_source_info.file;
|
delete this->metadata_source_info.file;
|
||||||
break;
|
break;
|
||||||
case DataSourceType::LooseSdFile:
|
case DataSourceType::LooseSdFile:
|
||||||
delete[] this->loose_source_info.path;
|
FreeTracked(AllocationType_FullPath, this->loose_source_info.path, std::strlen(this->loose_source_info.path) + 1);
|
||||||
break;
|
break;
|
||||||
case DataSourceType::Memory:
|
case DataSourceType::Memory:
|
||||||
std::free(static_cast<void *>(this->memory_source_info.data));
|
FreeTracked(AllocationType_Memory, this->memory_source_info.data, this->size);
|
||||||
break;
|
break;
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
}
|
}
|
||||||
@ -113,7 +159,7 @@ namespace ams::mitm::fs::romfs {
|
|||||||
NON_COPYABLE(BuildDirectoryContext);
|
NON_COPYABLE(BuildDirectoryContext);
|
||||||
NON_MOVEABLE(BuildDirectoryContext);
|
NON_MOVEABLE(BuildDirectoryContext);
|
||||||
|
|
||||||
std::unique_ptr<char[]> path;
|
char *path;
|
||||||
union {
|
union {
|
||||||
BuildDirectoryContext *parent;
|
BuildDirectoryContext *parent;
|
||||||
};
|
};
|
||||||
@ -139,16 +185,28 @@ namespace ams::mitm::fs::romfs {
|
|||||||
struct RootTag{};
|
struct RootTag{};
|
||||||
|
|
||||||
BuildDirectoryContext(RootTag) : parent(nullptr), child(nullptr), sibling(nullptr), file(nullptr), path_len(0), entry_offset(0), hash_value(0xFFFFFFFF) {
|
BuildDirectoryContext(RootTag) : parent(nullptr), child(nullptr), sibling(nullptr), file(nullptr), path_len(0), entry_offset(0), hash_value(0xFFFFFFFF) {
|
||||||
this->path = std::make_unique<char[]>(1);
|
this->path = static_cast<char *>(AllocateTracked(AllocationType_DirName, 1));
|
||||||
|
this->path[0] = '\x00';
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildDirectoryContext(const char *entry_name, size_t entry_name_len) : parent(nullptr), child(nullptr), sibling(nullptr), file(nullptr), entry_offset(0) {
|
BuildDirectoryContext(const char *entry_name, size_t entry_name_len) : parent(nullptr), child(nullptr), sibling(nullptr), file(nullptr), entry_offset(0) {
|
||||||
this->path_len = entry_name_len;
|
this->path_len = entry_name_len;
|
||||||
this->path = std::unique_ptr<char[]>(new char[this->path_len + 1]);
|
this->path = static_cast<char *>(AllocateTracked(AllocationType_DirName, this->path_len + 1));
|
||||||
std::memcpy(this->path.get(), entry_name, entry_name_len);
|
std::memcpy(this->path, entry_name, entry_name_len);
|
||||||
this->path[this->path_len] = '\x00';
|
this->path[this->path_len] = '\x00';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~BuildDirectoryContext() {
|
||||||
|
if (this->path != nullptr) {
|
||||||
|
FreeTracked(AllocationType_DirName, this->path, this->path_len + 1);
|
||||||
|
this->path = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *p) {
|
||||||
|
FreeTracked(AllocationType_BuildDirContext, p, sizeof(BuildDirectoryContext));
|
||||||
|
}
|
||||||
|
|
||||||
size_t GetPathLength() const {
|
size_t GetPathLength() const {
|
||||||
if (this->parent == nullptr) {
|
if (this->parent == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -165,7 +223,7 @@ namespace ams::mitm::fs::romfs {
|
|||||||
|
|
||||||
const size_t parent_len = this->parent->GetPath(dst);
|
const size_t parent_len = this->parent->GetPath(dst);
|
||||||
dst[parent_len] = '/';
|
dst[parent_len] = '/';
|
||||||
std::memcpy(dst + parent_len + 1, this->path.get(), this->path_len);
|
std::memcpy(dst + parent_len + 1, this->path, this->path_len);
|
||||||
dst[parent_len + 1 + this->path_len] = '\x00';
|
dst[parent_len + 1 + this->path_len] = '\x00';
|
||||||
return parent_len + 1 + this->path_len;
|
return parent_len + 1 + this->path_len;
|
||||||
}
|
}
|
||||||
@ -187,7 +245,7 @@ namespace ams::mitm::fs::romfs {
|
|||||||
NON_COPYABLE(BuildFileContext);
|
NON_COPYABLE(BuildFileContext);
|
||||||
NON_MOVEABLE(BuildFileContext);
|
NON_MOVEABLE(BuildFileContext);
|
||||||
|
|
||||||
std::unique_ptr<char[]> path;
|
char *path;
|
||||||
BuildDirectoryContext *parent;
|
BuildDirectoryContext *parent;
|
||||||
union {
|
union {
|
||||||
BuildFileContext *sibling;
|
BuildFileContext *sibling;
|
||||||
@ -203,11 +261,22 @@ namespace ams::mitm::fs::romfs {
|
|||||||
|
|
||||||
BuildFileContext(const char *entry_name, size_t entry_name_len, s64 sz, s64 o_o, DataSourceType type) : parent(nullptr), sibling(nullptr), offset(0), size(sz), orig_offset(o_o), entry_offset(0), hash_value(0xFFFFFFFF), source_type(type) {
|
BuildFileContext(const char *entry_name, size_t entry_name_len, s64 sz, s64 o_o, DataSourceType type) : parent(nullptr), sibling(nullptr), offset(0), size(sz), orig_offset(o_o), entry_offset(0), hash_value(0xFFFFFFFF), source_type(type) {
|
||||||
this->path_len = entry_name_len;
|
this->path_len = entry_name_len;
|
||||||
this->path = std::unique_ptr<char[]>(new char[this->path_len + 1]);
|
this->path = static_cast<char *>(AllocateTracked(AllocationType_FileName, this->path_len + 1));
|
||||||
std::memcpy(this->path.get(), entry_name, entry_name_len);
|
std::memcpy(this->path, entry_name, entry_name_len);
|
||||||
this->path[this->path_len] = 0;
|
this->path[this->path_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~BuildFileContext() {
|
||||||
|
if (this->path != nullptr) {
|
||||||
|
FreeTracked(AllocationType_FileName, this->path, this->path_len + 1);
|
||||||
|
this->path = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *p) {
|
||||||
|
FreeTracked(AllocationType_BuildFileContext, p, sizeof(BuildFileContext));
|
||||||
|
}
|
||||||
|
|
||||||
size_t GetPathLength() const {
|
size_t GetPathLength() const {
|
||||||
if (this->parent == nullptr) {
|
if (this->parent == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -224,7 +293,7 @@ namespace ams::mitm::fs::romfs {
|
|||||||
|
|
||||||
const size_t parent_len = this->parent->GetPath(dst);
|
const size_t parent_len = this->parent->GetPath(dst);
|
||||||
dst[parent_len] = '/';
|
dst[parent_len] = '/';
|
||||||
std::memcpy(dst + parent_len + 1, this->path.get(), this->path_len);
|
std::memcpy(dst + parent_len + 1, this->path, this->path_len);
|
||||||
dst[parent_len + 1 + this->path_len] = '\x00';
|
dst[parent_len + 1 + this->path_len] = '\x00';
|
||||||
return parent_len + 1 + this->path_len;
|
return parent_len + 1 + this->path_len;
|
||||||
}
|
}
|
||||||
@ -248,6 +317,8 @@ namespace ams::mitm::fs::romfs {
|
|||||||
class Builder {
|
class Builder {
|
||||||
NON_COPYABLE(Builder);
|
NON_COPYABLE(Builder);
|
||||||
NON_MOVEABLE(Builder);
|
NON_MOVEABLE(Builder);
|
||||||
|
public:
|
||||||
|
using SourceInfoVector = std::vector<SourceInfo, TrackedAllocator<AllocationType_SourceInfo, SourceInfo>>;
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Comparator {
|
struct Comparator {
|
||||||
@ -270,13 +341,13 @@ namespace ams::mitm::fs::romfs {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<AllocationType AllocType, typename T>
|
||||||
using ContextSet = std::set<std::unique_ptr<T>, Comparator<T>>;
|
using ContextSet = std::set<std::unique_ptr<T>, Comparator<T>, TrackedAllocator<AllocType, std::unique_ptr<T>>>;
|
||||||
private:
|
private:
|
||||||
ncm::ProgramId m_program_id;
|
ncm::ProgramId m_program_id;
|
||||||
BuildDirectoryContext *m_root;
|
BuildDirectoryContext *m_root;
|
||||||
ContextSet<BuildDirectoryContext> m_directories;
|
ContextSet<AllocationType_DirContextSet, BuildDirectoryContext> m_directories;
|
||||||
ContextSet<BuildFileContext> m_files;
|
ContextSet<AllocationType_FileContextSet, BuildFileContext> m_files;
|
||||||
size_t m_num_dirs;
|
size_t m_num_dirs;
|
||||||
size_t m_num_files;
|
size_t m_num_files;
|
||||||
size_t m_dir_table_size;
|
size_t m_dir_table_size;
|
||||||
@ -299,7 +370,7 @@ namespace ams::mitm::fs::romfs {
|
|||||||
void AddSdFiles();
|
void AddSdFiles();
|
||||||
void AddStorageFiles(ams::fs::IStorage *storage, DataSourceType source_type);
|
void AddStorageFiles(ams::fs::IStorage *storage, DataSourceType source_type);
|
||||||
|
|
||||||
void Build(std::vector<SourceInfo> *out_infos);
|
void Build(SourceInfoVector *out_infos);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -713,4 +713,8 @@ namespace ams::pm::impl {
|
|||||||
R_RETURN(resource::GetResourceLimitValues(out_cur_val, out_lim_val, static_cast<ResourceLimitGroup>(group), static_cast<svc::LimitableResource>(resource)));
|
R_RETURN(resource::GetResourceLimitValues(out_cur_val, out_lim_val, static_cast<ResourceLimitGroup>(group), static_cast<svc::LimitableResource>(resource)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size) {
|
||||||
|
R_RETURN(resource::BoostSystemMemoryResourceLimitForMitm(boost_size));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,5 +55,6 @@ namespace ams::pm::impl {
|
|||||||
Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out);
|
Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out);
|
||||||
Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out);
|
Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out);
|
||||||
Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource);
|
Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource);
|
||||||
|
Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,16 @@ namespace ams::pm::resource {
|
|||||||
constinit os::SdkMutex g_resource_limit_lock;
|
constinit os::SdkMutex g_resource_limit_lock;
|
||||||
constinit os::NativeHandle g_resource_limit_handles[ResourceLimitGroup_Count];
|
constinit os::NativeHandle g_resource_limit_handles[ResourceLimitGroup_Count];
|
||||||
constinit spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
|
constinit spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
|
||||||
constinit u64 g_system_memory_boost_size = 0;
|
|
||||||
constinit u64 g_extra_threads_available[ResourceLimitGroup_Count];
|
constinit u64 g_extra_threads_available[ResourceLimitGroup_Count];
|
||||||
|
|
||||||
|
constinit os::SdkMutex g_system_memory_boost_lock;
|
||||||
|
constinit u64 g_system_memory_boost_size = 0;
|
||||||
|
constinit u64 g_system_memory_boost_size_for_mitm = 0;
|
||||||
|
|
||||||
|
ALWAYS_INLINE u64 GetCurrentSystemMemoryBoostSize() {
|
||||||
|
return g_system_memory_boost_size + g_system_memory_boost_size_for_mitm;
|
||||||
|
}
|
||||||
|
|
||||||
constinit u64 g_resource_limits[ResourceLimitGroup_Count][svc::LimitableResource_Count] = {
|
constinit u64 g_resource_limits[ResourceLimitGroup_Count][svc::LimitableResource_Count] = {
|
||||||
[ResourceLimitGroup_System] = {
|
[ResourceLimitGroup_System] = {
|
||||||
[svc::LimitableResource_PhysicalMemoryMax] = 0, /* Initialized dynamically later. */
|
[svc::LimitableResource_PhysicalMemoryMax] = 0, /* Initialized dynamically later. */
|
||||||
@ -220,6 +227,47 @@ namespace ams::pm::resource {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result BoostSystemMemoryResourceLimitLocked(u64 normal_boost, u64 mitm_boost) {
|
||||||
|
/* Check pre-conditions. */
|
||||||
|
AMS_ASSERT(g_system_memory_boost_lock.IsLockedByCurrentThread());
|
||||||
|
|
||||||
|
/* Determine total boost. */
|
||||||
|
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());
|
||||||
|
|
||||||
|
const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size;
|
||||||
|
{
|
||||||
|
std::scoped_lock lk(g_resource_limit_lock);
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
R_TRY(svc::SetUnsafeLimit(boost_size));
|
||||||
|
R_ABORT_UNLESS(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
||||||
|
} else {
|
||||||
|
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
||||||
|
R_ABORT_UNLESS(svc::SetUnsafeLimit(boost_size));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const u64 new_sys_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_System] + boost_size;
|
||||||
|
if (boost_size < GetCurrentSystemMemoryBoostSize()) {
|
||||||
|
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size));
|
||||||
|
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
||||||
|
} else {
|
||||||
|
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
||||||
|
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_system_memory_boost_size = normal_boost;
|
||||||
|
g_system_memory_boost_size_for_mitm = mitm_boost;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resource API. */
|
/* Resource API. */
|
||||||
@ -352,37 +400,19 @@ namespace ams::pm::resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result BoostSystemMemoryResourceLimit(u64 boost_size) {
|
Result BoostSystemMemoryResourceLimit(u64 boost_size) {
|
||||||
/* Don't allow all application memory to be taken away. */
|
/* Ensure only one boost change happens at a time. */
|
||||||
R_UNLESS(boost_size <= g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize());
|
std::scoped_lock lk(g_system_memory_boost_lock);
|
||||||
|
|
||||||
const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size;
|
/* Boost to the appropriate total amount. */
|
||||||
{
|
R_RETURN(BoostSystemMemoryResourceLimitLocked(boost_size, g_system_memory_boost_size_for_mitm));
|
||||||
std::scoped_lock lk(g_resource_limit_lock);
|
}
|
||||||
|
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size) {
|
||||||
/* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */
|
/* Ensure only one boost change happens at a time. */
|
||||||
if (boost_size < g_system_memory_boost_size) {
|
std::scoped_lock lk(g_system_memory_boost_lock);
|
||||||
R_TRY(svc::SetUnsafeLimit(boost_size));
|
|
||||||
R_ABORT_UNLESS(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
|
||||||
} else {
|
|
||||||
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
|
||||||
R_ABORT_UNLESS(svc::SetUnsafeLimit(boost_size));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const u64 new_sys_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_System] + boost_size;
|
|
||||||
if (boost_size < g_system_memory_boost_size) {
|
|
||||||
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size));
|
|
||||||
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
|
||||||
} else {
|
|
||||||
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
|
|
||||||
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_system_memory_boost_size = boost_size;
|
/* Boost to the appropriate total amount. */
|
||||||
}
|
R_RETURN(BoostSystemMemoryResourceLimitLocked(g_system_memory_boost_size, boost_size));
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result BoostApplicationThreadResourceLimit() {
|
Result BoostApplicationThreadResourceLimit() {
|
||||||
|
@ -24,6 +24,8 @@ namespace ams::pm::resource {
|
|||||||
Result BoostApplicationThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostSystemThreadResourceLimit();
|
||||||
|
|
||||||
|
Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size);
|
||||||
|
|
||||||
os::NativeHandle GetResourceLimitHandle(ResourceLimitGroup group);
|
os::NativeHandle GetResourceLimitHandle(ResourceLimitGroup group);
|
||||||
os::NativeHandle GetResourceLimitHandle(const ldr::ProgramInfo *info);
|
os::NativeHandle GetResourceLimitHandle(const ldr::ProgramInfo *info);
|
||||||
|
|
||||||
|
@ -87,4 +87,8 @@ namespace ams::pm {
|
|||||||
R_RETURN(impl::BoostSystemThreadResourceLimit());
|
R_RETURN(impl::BoostSystemThreadResourceLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ShellService::AtmosphereBoostSystemMemoryResourceLimitForMitm(u64 boost_size) {
|
||||||
|
R_RETURN(impl::BoostSystemMemoryResourceLimitForMitm(boost_size));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ namespace ams::pm {
|
|||||||
Result BoostApplicationThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
void GetBootFinishedEventHandle(sf::OutCopyHandle out);
|
void GetBootFinishedEventHandle(sf::OutCopyHandle out);
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostSystemThreadResourceLimit();
|
||||||
|
|
||||||
|
/* Atmosphere extension command implementations. */
|
||||||
|
Result AtmosphereBoostSystemMemoryResourceLimitForMitm(u64 boost_size);
|
||||||
};
|
};
|
||||||
static_assert(pm::impl::IsIShellInterface<ShellService>);
|
static_assert(pm::impl::IsIShellInterface<ShellService>);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user