Compare commits

..

4 Commits

Author SHA1 Message Date
Michael Scire
4859bcc0fe boot: use #embed for fusee 2025-05-04 13:23:38 -07:00
Michael Scire
0ecd822c26 exo: use #embed for loader stub 2025-05-04 13:23:19 -07:00
Michael Scire
b1e0dad506 fusee: use embed in mtc/sdram param scripts 2025-04-26 14:57:10 -07:00
Michael Scire
c55606cfdb ams: basic support for compiling with gcc 15 2025-04-26 14:53:08 -07:00
109 changed files with 725 additions and 1968 deletions

View File

@@ -13,6 +13,7 @@ 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

View File

@@ -50,7 +50,6 @@ 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
@@ -88,7 +87,6 @@ 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
@@ -106,7 +104,6 @@ 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

View File

@@ -1,29 +1,4 @@
# 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.
+ 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!
+ 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.

2
emummc/README.md vendored
View File

@@ -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 - 19.0.0**
## Features
* Arbitrary SDMMC backend selection

View File

@@ -75,8 +75,6 @@
#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
@@ -163,8 +161,6 @@ 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) {
@@ -286,10 +282,6 @@ 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);
}

View File

@@ -110,9 +110,6 @@ 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,
};

View File

@@ -1,59 +0,0 @@
/*
* 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_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__

View File

@@ -1,59 +0,0 @@
/*
* 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_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 0x1AF520
// 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__

View File

@@ -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 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
.byte 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70
/* Mariko Production Master Kek Source. */
.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
.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. */
@@ -110,7 +110,6 @@ _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. */
@@ -132,7 +131,6 @@ _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. */
@@ -151,7 +149,6 @@ _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. */
@@ -170,7 +167,6 @@ _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. */
@@ -189,4 +185,3 @@ _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. */

View File

@@ -94,7 +94,7 @@ namespace ams::secmon::boot {
}
/* Check that the key generation is one that we can use. */
static_assert(pkg1::KeyGeneration_Count == 20);
static_assert(pkg1::KeyGeneration_Count == 19);
if (key_generation >= pkg1::KeyGeneration_Count) {
return false;
}

View File

@@ -23,17 +23,17 @@ namespace ams::nxboot {
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */
0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
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. */
0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
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. */
0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8
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] = {
@@ -73,7 +73,6 @@ 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] = {
@@ -93,7 +92,6 @@ 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] = {
@@ -113,7 +111,6 @@ 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] = {
@@ -136,7 +133,6 @@ 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] = {
@@ -159,7 +155,6 @@ 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] = {};

View File

@@ -80,7 +80,7 @@ namespace ams::nxboot {
}
/* Check that the key generation is one that we can use. */
static_assert(pkg1::KeyGeneration_Count == 20);
static_assert(pkg1::KeyGeneration_Count == 19);
if (key_generation >= pkg1::KeyGeneration_Count) {
return false;
}

View File

@@ -263,8 +263,6 @@ 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:

View File

@@ -180,9 +180,6 @@ namespace ams::nxboot {
FsVersion_19_0_0,
FsVersion_19_0_0_Exfat,
FsVersion_20_0_0,
FsVersion_20_0_0_Exfat,
FsVersion_Count,
};
@@ -275,9 +272,6 @@ 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) {
@@ -667,16 +661,6 @@ 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, 0x1B3745, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1));
break;
default:
break;
}

View File

@@ -39,7 +39,6 @@ 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,

View File

@@ -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 = 0x17;
constexpr inline int CurrentBootloaderVersion = 0x16;
struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>;

View File

@@ -177,7 +177,6 @@ namespace ams::fuse {
}
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_20_0_0,
TargetFirmware_19_0_0,
TargetFirmware_17_0_0,
TargetFirmware_16_0_0,

View File

@@ -200,11 +200,6 @@ 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<const KPageTable *>(pt)->NoteUpdated();
}
private:
Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll);

View File

@@ -49,8 +49,6 @@ 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;
@@ -146,8 +144,8 @@ namespace ams::kern::arch::arm64 {
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) 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;
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<uintptr_t>(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0;

View File

@@ -22,139 +22,49 @@ namespace ams::kern::arch::arm64 {
class UserspaceAccess {
private:
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);
};
static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src);
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<uintptr_t>(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) {
return false;
}
return Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(dst, src);
return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src);
}
static s32 CopyStringFromUser(void *dst, const void *src, size_t size) {
return Impl::CopyStringFromUser(dst, src, size);
}
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 bool CopyMemoryToUser(void *dst, const void *src, size_t size) {
return Impl::CopyMemoryToUser(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 CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) {
return Impl::CopyMemoryToUserAligned32Bit(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 CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) {
return Impl::CopyMemoryToUserAligned64Bit(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 CopyMemoryToUserSize32Bit(void *dst, const void *src) {
return Impl::CopyMemoryToUserSize32Bit(dst, src);
}
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 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);
}
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);
};

View File

@@ -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, size_t code_size);
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);

View File

@@ -99,7 +99,6 @@ 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);

View File

@@ -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_uninitialized_random_generator{true};
static constinit inline bool s_initialized_random_generator;
static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize};
static constinit inline KSpinLock s_random_lock;
public:

View File

@@ -94,11 +94,7 @@ namespace ams::kern {
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const {
if (m_resource_limit != nullptr) {
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
} else {
return 0;
}
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
}
ALWAYS_INLINE size_t GetSize() const { return m_resource_size; }

View File

@@ -25,35 +25,35 @@ namespace ams::kern {
friend class KSystemControl;
private:
struct KTargetSystemData {
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;
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 inline constinit bool s_is_uninitialized = true;
static inline constinit bool s_is_initialized = false;
static inline constinit const volatile KTargetSystemData s_data = {
.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,
.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_uninitialized = false; }
static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; }
public:
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); }
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; }
};
}

View File

@@ -109,31 +109,12 @@ namespace ams::kern::arch::arm64 {
return insn;
}
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 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. */
far = 0;
} else {
/* If the faulting address is a kernel address, set ISFC = 4. */
if (far >= ams::svc::AddressMemoryRegion39Size) {
esr = (esr & 0xFFFFFFC0) | 4;
}
}
}
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();
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);
@@ -184,7 +165,7 @@ namespace ams::kern::arch::arm64 {
}
/* Save the debug parameters to the current thread. */
GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data);
GetCurrentThread().SaveDebugParams(far, esr, data);
/* Get the exception type. */
u32 type;
@@ -406,6 +387,7 @@ 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. */
@@ -450,28 +432,9 @@ 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 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. */
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 (ec) {
switch ((esr >> 26) & 0x3F) {
case EsrEc_Unknown:
case EsrEc_IllegalExecution:
case EsrEc_BkptInstruction:

View File

@@ -752,10 +752,13 @@ namespace ams::kern::arch::arm64 {
while (true) {
/* Try to merge. */
KVirtualAddress freed_table = Null<KVirtualAddress>;
if (!impl.MergePages(std::addressof(freed_table), context, &KPageTable::NoteUpdatedCallback, this)) {
if (!impl.MergePages(std::addressof(freed_table), context)) {
break;
}
/* Note that we updated. */
this->NoteUpdated();
/* Free the page. */
if (freed_table != Null<KVirtualAddress>) {
ClearPageTable(freed_table);
@@ -813,7 +816,8 @@ namespace ams::kern::arch::arm64 {
}
/* Separate. */
impl.SeparatePages(entry, context, virt_addr, GetPointer<PageTableEntry>(table), &KPageTable::NoteUpdatedCallback, this);
impl.SeparatePages(entry, context, virt_addr, GetPointer<PageTableEntry>(table));
this->NoteUpdated();
}
R_SUCCEED();
@@ -1021,9 +1025,6 @@ 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. */

View File

@@ -219,7 +219,7 @@ namespace ams::kern::arch::arm64 {
return is_block;
}
bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt) {
bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) {
/* We want to upgrade the pages by one step. */
if (context->is_contiguous) {
/* We can't merge an L1 table. */
@@ -251,7 +251,6 @@ 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;
@@ -286,7 +285,6 @@ 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;
@@ -296,7 +294,7 @@ namespace ams::kern::arch::arm64 {
return true;
}
void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const {
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. */
@@ -307,7 +305,6 @@ 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;
@@ -328,12 +325,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 = context->level_entries[context->level]->GetSoftwareReservedBits();
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<size_t>(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous);

View File

@@ -24,12 +24,12 @@ _ZN3ams4kern4arch5arm6432UserspaceAccessFunctionAreaBeginEv:
/* ================ All Userspace Access Functions after this line. ================ */
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUser(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm:
/* Check if there's anything to copy. */
cmp x2, #0
b.eq 2f
@@ -48,12 +48,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm:
/* Check if there are 0x40 bytes to copy */
cmp x2, #0x3F
b.ls 1f
@@ -72,7 +72,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv
add x0, x0, #0x40
add x1, x1, #0x40
sub x2, x2, #0x40
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm
b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm
1: /* We have less than 0x40 bytes to copy. */
cmp x2, #0
@@ -87,12 +87,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm:
/* Check if there are 0x40 bytes to copy */
cmp x2, #0x3F
b.ls 1f
@@ -111,7 +111,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv
add x0, x0, #0x40
add x1, x1, #0x40
sub x2, x2, #0x40
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm
b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm
1: /* We have less than 0x40 bytes to copy. */
cmp x2, #0
@@ -126,12 +126,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, %function
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv:
_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv:
/* Just load and store a u64. */
ldtr x2, [x1]
str x2, [x0]
@@ -140,12 +140,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, %function
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv:
_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv:
/* Just load and store a u32. */
ldtr w2, [x1]
str w2, [x0]
@@ -154,12 +154,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, %function
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv:
_ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv:
/* Just load and store a u32. */
/* NOTE: This is done with supervisor access permissions. */
ldr w2, [x1]
@@ -169,12 +169,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSu
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm:
/* Check if there's anything to copy. */
cmp x2, #0
b.eq 3f
@@ -204,12 +204,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm:
mov x0, #0
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUser(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm:
/* Check if there's anything to copy. */
cmp x2, #0
b.eq 2f
@@ -228,12 +228,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm:
/* Check if there are 0x40 bytes to copy */
cmp x2, #0x3F
b.ls 1f
@@ -252,7 +252,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK
add x0, x0, #0x40
add x1, x1, #0x40
sub x2, x2, #0x40
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm
b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm
1: /* We have less than 0x40 bytes to copy. */
cmp x2, #0
@@ -267,12 +267,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm:
/* Check if there are 0x40 bytes to copy */
cmp x2, #0x3F
b.ls 1f
@@ -291,7 +291,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
add x0, x0, #0x40
add x1, x1, #0x40
sub x2, x2, #0x40
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm
b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm
1: /* We have less than 0x40 bytes to copy. */
cmp x2, #0
@@ -306,12 +306,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
_ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv:
/* Just load and store a u32. */
ldr w2, [x1]
sttr w2, [x0]
@@ -320,12 +320,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::CopyStringToUser(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm:
/* Check if there's anything to copy. */
cmp x2, #0
b.eq 3f
@@ -355,12 +355,114 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm:
mov x0, #0
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::ClearMemory(void *dst, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
_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:
/* Load the value from the address. */
ldaxr w4, [x1]
@@ -375,7 +477,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
stlxr w6, w5, [x1]
/* If we failed to store, try again. */
cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj
cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj
/* We're done. */
str w4, [x0]
@@ -383,12 +485,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
ret
/* 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
/* 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
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii:
_ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii:
/* Load the value from the address. */
ldaxr w4, [x1]
@@ -406,19 +508,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii:
stlxr w5, w3, [x1]
/* If we failed to store, try again. */
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii
2: /* We're done. */
str w4, [x0]
mov x0, #1
ret
/* 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
/* 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
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i:
_ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i:
/* Load the value from the address. */
ldaxr w3, [x1]
@@ -437,19 +539,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i:
stlxr w5, w4, [x1]
/* If we failed to store, try again. */
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i
2: /* We're done. */
str w3, [x0]
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::StoreDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, %function
/* ams::kern::arch::arm64::UserspaceAccess::StoreDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm:
_ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm:
/* Check if we have any work to do. */
cmp x1, x0
b.eq 2f
@@ -464,12 +566,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm:
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::FlushDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, %function
/* ams::kern::arch::arm64::UserspaceAccess::FlushDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm:
_ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm:
/* Check if we have any work to do. */
cmp x1, x0
b.eq 2f
@@ -484,12 +586,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm:
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::InvalidateDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, %function
/* ams::kern::arch::arm64::UserspaceAccess::InvalidateDataCache(uintptr_t start, uintptr_t end) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm:
_ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm:
/* Check if we have any work to do. */
cmp x1, x0
b.eq 2f
@@ -504,12 +606,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f
@@ -554,12 +656,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm:
mov w9, #0xFFFFFFFF
b 2b
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f
@@ -604,12 +706,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm:
mov w9, #0xFFFFFFFF
b 2b
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f
@@ -654,12 +756,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm:
mov w9, #0xFFFFFFFF
b 2b
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f
@@ -699,12 +801,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f
@@ -744,12 +846,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm:
mov x0, #1
ret
/* 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
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm:
_ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm:
/* Check if we have any work to do. */
cmp x2, #0
b.eq 3f

View File

@@ -361,9 +361,7 @@ namespace ams::kern::board::nintendo::nx {
}();
/* Return (possibly) adjusted size. */
/* 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;
constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
}
@@ -407,22 +405,22 @@ namespace ams::kern::board::nintendo::nx {
/* Configure KTargetSystem. */
volatile auto *ts = const_cast<volatile KTargetSystem::KTargetSystemData *>(std::addressof(KTargetSystem::s_data));
{
/* Set whether we're in debug mode. */
/* Set IsDebugMode. */
{
ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode);
ts->is_debug_mode = GetConfigBool(smc::ConfigItem::IsDebugMode);
/* If we're not in debug mode, we don't want to initialize uart logging. */
ts->disable_debug_logging = ts->is_not_debug_mode;
/* If debug mode, we want to initialize uart logging. */
ts->enable_debug_logging = ts->is_debug_mode;
}
/* Set Kernel Configuration. */
{
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
ts->disable_debug_memory_fill = !kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
ts->disable_user_exception_handlers = !kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
ts->disable_dynamic_resource_limits = kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
ts->disable_user_pmu_access = !kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
ts->enable_debug_memory_fill = kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
ts->enable_user_exception_handlers = kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
ts->enable_dynamic_resource_limits = !kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
ts->enable_user_pmu_access = kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
/* Configure call smc on panic. */
*const_cast<volatile bool *>(std::addressof(g_call_smc_on_panic)) = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
@@ -432,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->disable_kernel_debugging = !GetConfigBool(smc::ConfigItem::DisableProgramVerification);
ts->enable_kernel_debugging = GetConfigBool(smc::ConfigItem::DisableProgramVerification);
}
}
}
@@ -526,7 +524,7 @@ namespace ams::kern::board::nintendo::nx {
KScopedSpinLock lk(s_random_lock);
if (AMS_LIKELY(!s_uninitialized_random_generator)) {
if (AMS_LIKELY(s_initialized_random_generator)) {
return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); });
} else {
return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc);
@@ -537,7 +535,7 @@ namespace ams::kern::board::nintendo::nx {
KScopedInterruptDisable intr_disable;
KScopedSpinLock lk(s_random_lock);
if (AMS_LIKELY(!s_uninitialized_random_generator)) {
if (AMS_LIKELY(s_initialized_random_generator)) {
return s_random_generator.GenerateRandomU64();
} else {
return GenerateRandomU64FromSmc();

View File

@@ -66,39 +66,12 @@ namespace ams::kern {
}
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type, size_t code_size) {
MESOSPHERE_UNUSED(code_size);
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress();
}
size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
/* 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;
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize();
}
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {

View File

@@ -229,12 +229,9 @@ 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<ams::svc::CreateProcessFlag>(out->flags), as_type, out->code_num_pages);
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
const uintptr_t map_end = map_start + map_size;
out->code_address = map_start + start_address;

View File

@@ -118,78 +118,29 @@ 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<uintptr_t>(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 {
/* Determine the range to search in. */
KProcessAddress search_start = Null<KProcessAddress>;
KProcessAddress search_end = Null<KProcessAddress>;
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()) {
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()) {
break;
}
/* We only want to consider free blocks. */
if (it->GetState() != KMemoryState_Free) {
continue;
}
/* Determine the candidate range. */
KProcessAddress candidate_start = Null<KProcessAddress>;
KProcessAddress candidate_end = Null<KProcessAddress>;
if (!this->GetRegionForFindFreeArea(std::addressof(candidate_start), std::addressof(candidate_end), it->GetAddress(), it->GetNumPages(), num_pages, alignment, offset, guard_pages)) {
continue;
}
KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress();
area += guard_pages * PageSize;
/* Try the suggested candidate (coercing into the search region if needed). */
KProcessAddress candidate = candidate_start;
if (candidate < search_start) {
candidate = search_start;
}
const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset;
area = (area <= offset_area) ? offset_area : offset_area + alignment;
/* Check if the candidate is valid. */
if (candidate <= search_end && candidate <= candidate_end) {
return candidate;
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;
}
}
}

View File

@@ -141,7 +141,7 @@ namespace ams::kern {
/* Define helpers. */
auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
return KAddressSpaceInfo::GetAddressSpaceStart(flags, type, code_size);
return KAddressSpaceInfo::GetAddressSpaceStart(flags, type);
};
auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
return KAddressSpaceInfo::GetAddressSpaceSize(flags, type);
@@ -155,6 +155,12 @@ 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;
@@ -1333,37 +1339,34 @@ 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<KProcessAddress>;
KProcessAddress search_start = Null<KProcessAddress>;
KProcessAddress search_end = Null<KProcessAddress>;
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 (num_pages <= region_num_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, (search_end - search_start) / alignment) * alignment;
const KProcessAddress candidate = search_start + random_offset;
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;
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<KProcessAddress>) {
/* 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_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);
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);
}
}
/* Find the first free area. */
if (address == Null<KProcessAddress>) {
address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages, alignment, offset, guard_pages);
@@ -1789,24 +1792,19 @@ 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_ChangePermissionsAndRefresh : OperationType_ChangePermissions;
const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions;
R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, 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 (was_x) {
if (is_x) {
for (const auto &block : pg) {
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize());
}
cpu::InvalidateEntireInstructionCache();
}
@@ -2548,11 +2546,6 @@ 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));
@@ -2576,9 +2569,8 @@ 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(nullptr, std::addressof(old_perm), nullptr, std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None));
R_TRY(this->CheckMemoryState(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());
@@ -2595,11 +2587,6 @@ namespace ams::kern {
const KPageProperties properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None };
R_TRY(this->Operate(updater.GetPageList(), address, num_pages, Null<KPhysicalAddress>, 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);

View File

@@ -221,7 +221,7 @@ namespace ams::kern {
}
/* Set max memory. */
m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(m_flags), KAddressSpaceInfo::Type_Heap);
m_max_process_memory = m_page_table.GetHeapRegionSize();
/* Generate random entropy. */
KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy));

View File

@@ -102,10 +102,10 @@ namespace ams::kern {
/* Randomness for Initialization. */
void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) {
if (AMS_UNLIKELY(s_uninitialized_random_generator)) {
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
const u64 seed = KHardwareTimer::GetTick();
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
s_uninitialized_random_generator = false;
s_initialized_random_generator = true;
}
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_uninitialized_random_generator)) {
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
const u64 seed = KHardwareTimer::GetTick();
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
s_uninitialized_random_generator = false;
s_initialized_random_generator = true;
}
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_uninitialized_random_generator)) {
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
s_uninitialized_random_generator = false;
s_initialized_random_generator = true;
}
/* Initialize debug logging. */

View File

@@ -59,9 +59,7 @@ namespace ams::kern {
memory_reservation.Commit();
/* Open reference to our resource limit. */
if (m_resource_limit != nullptr) {
m_resource_limit->Open();
}
m_resource_limit->Open();
/* Set ourselves as initialized. */
m_is_initialized = true;
@@ -78,14 +76,11 @@ namespace ams::kern {
/* Free our secure memory. */
KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool);
/* Clean up our resource usage. */
if (m_resource_limit != nullptr) {
/* Release the memory reservation. */
m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize());
/* 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) {

View File

@@ -74,45 +74,43 @@ 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<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
/* Initialize the KPageBuffer slab heap. */
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);
/* 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));
/* Initialize the fixed-size slabheaps. */
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));
s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize);
s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize);
/* 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<KPageTableManager::RefCount>(address + size));
/* 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<KSystemResource>(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);
/* 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));
/* 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<KSystemResource>(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);
s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap));
/* 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<KSystemResource>(std::addressof(s_app_system_resource));
KAutoObject::Create<KSystemResource>(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() {

View File

@@ -109,12 +109,11 @@ 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<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size);
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_end = map_start + map_size;
}
@@ -124,7 +123,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<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size);
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_end = map_start + map_size;
}
@@ -134,7 +133,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<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit, code_size);
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Heap);
@@ -182,6 +181,7 @@ 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;

View File

@@ -171,8 +171,6 @@ 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);

View File

@@ -181,13 +181,6 @@
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) \
@@ -349,7 +342,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(LastDvfsThresholdTrippedDeprecated, 156, 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 ) \
@@ -455,7 +448,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(OscillatorClockDeprecated, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(OscillatorClock, 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 ) \
@@ -463,8 +456,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(ModuleClockEnableFlagsDeprecated, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModulePowerEnableFlagsDeprecated, 271, PowerClockInfo, FieldType_U8Array, 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(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
@@ -733,7 +726,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(DramIdDeprecated, 540, PowerClockInfo, FieldType_NumericU32, 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 ) \
@@ -888,44 +881,6 @@
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 ) \
@@ -954,10 +909,5 @@
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(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 ) \
HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None )

View File

@@ -20,28 +20,26 @@
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
#include <stratosphere/time/time_steady_clock_time_point.hpp>
#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<erpt::AttachmentId> 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<erpt::AttachmentId> 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)
#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<erpt::AttachmentId> 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)
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)

View File

@@ -17,16 +17,13 @@
#include <vapours.hpp>
#include <stratosphere/erpt/erpt_types.hpp>
#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<erpt::StorageUsageStatistics> 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<u32> 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<u32> out), (out), hos::Version_20_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<erpt::StorageUsageStatistics> 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)
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F)

View File

@@ -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, ncm::StorageId storage_id);
Result MountCode(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);
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);
}

View File

@@ -150,8 +150,7 @@ namespace ams::fssrv {
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id);
Result OpenCodeFileSystemDeprecated2(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id);
Result OpenCodeFileSystemDeprecated3(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id);
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<bool> out, u64 process_id);
};
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
@@ -175,16 +174,11 @@ namespace ams::fssrv {
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<bool> out, u64 process_id) {
AMS_UNUSED(out, process_id);
R_THROW(fs::ResultPortAcceptableCountLimited());

View File

@@ -21,13 +21,12 @@
#include <stratosphere/fs/fs_content_attributes.hpp>
/* 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<bool> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<bool> 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)

View File

@@ -83,12 +83,8 @@ 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,

View File

@@ -19,14 +19,14 @@
#include <stratosphere/ldr/ldr_types.hpp>
#include <stratosphere/sf.hpp>
#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<ldr::ProgramInfo> 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<ldr::PinId> 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<bool> out, ncm::ProgramId program_id), (out, program_id)) \
AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> 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<ldr::PinId> 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), (proc_h, id, flags, std::move(reslimit_h))) \
AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \
AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out<ldr::PinId> 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<bool> out, ncm::ProgramId program_id), (out, program_id)) \
AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \
AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out<ldr::PinId> 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)

View File

@@ -20,15 +20,15 @@
namespace ams::ldr::pm {
/* Process Manager API. */
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 CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit);
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
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, ldr::ProgramAttributes attrs);
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc);
Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
}

View File

@@ -20,7 +20,6 @@
#include <stratosphere/ncm/ncm_program_location.hpp>
#include <stratosphere/sf/sf_buffer_tags.hpp>
#include <stratosphere/ncm/ncm_content_meta_platform.hpp>
#include <stratosphere/fs/fs_content_attributes.hpp>
namespace ams::ldr {
@@ -266,10 +265,4 @@ namespace ams::ldr {
};
static_assert(sizeof(Npdm) == 0x80 && util::is_pod<Npdm>::value, "Npdm definition!");
struct ProgramAttributes {
ncm::ContentMetaPlatform platform;
fs::ContentAttributes content_attributes;
};
static_assert(sizeof(ProgramAttributes) == 2 && util::is_pod<ProgramAttributes>::value, "ProgramAttributes definition!");
}

View File

@@ -226,11 +226,6 @@ 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));
}
};
}

View File

@@ -44,8 +44,7 @@
AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out<u8> 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<ncm::ContentInfo> 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<ncm::ContentInfo> 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<ncm::ContentMetaPlatform> out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) \
AMS_SF_METHOD_INFO(C, H, 27, Result, HasAttributes, (sf::Out<u8> out, u8 attr_mask), (out, attr_mask), hos::Version_20_0_0)
AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out<ncm::ContentMetaPlatform> 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)

View File

@@ -72,7 +72,6 @@ namespace ams::ncm {
Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type);
Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset);
Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key);
Result HasAttributes(sf::Out<u8> out, u8 attr_mask);
};
static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>);

View File

@@ -121,15 +121,13 @@ 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 || program_id == AtmosphereProgramId::AtmosphereMemlet;
return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager;
}
inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &) {

View File

@@ -450,9 +450,6 @@ 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();
}

View File

@@ -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, nullptr));
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags));
ManagerImpl::NotifyAll();
@@ -142,11 +142,6 @@ namespace ams::erpt::srv {
R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size));
}
Result ContextImpl::SubmitAttachmentWithLz4Compression(ams::sf::Out<AttachmentId> 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<const ContextEntry *>( ctx_buffer.GetPointer());
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
@@ -159,7 +154,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, nullptr));
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags));
ManagerImpl::NotifyAll();
@@ -174,29 +169,6 @@ 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<const ContextEntry *>( ctx_buffer.GetPointer());
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
const ReportMetaData *meta = reinterpret_cast<const ReportMetaData *>(meta_buffer.GetPointer());
const u32 ctx_size = static_cast<u32>(ctx_buffer.GetSize());
const u32 data_size = static_cast<u32>(data_buffer.GetSize());
const u32 meta_size = static_cast<u32>(meta_buffer.GetSize());
const AttachmentId *attachments = reinterpret_cast<const AttachmentId *>(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));
}

View File

@@ -35,8 +35,6 @@ 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<AttachmentId> 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);

View File

@@ -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(), nullptr));
R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags()));
R_SUCCEED();
}

View File

@@ -51,8 +51,8 @@ namespace ams::erpt::srv {
R_RETURN(JournalForReports::DeleteReport(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));
Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) {
R_RETURN(JournalForAttachments::GetAttachmentList(out, report_id));
}
util::Uuid Journal::GetJournalId() {

View File

@@ -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(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id);
static Result GetAttachmentList(AttachmentList *out, 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(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id);
static Result GetAttachmentList(AttachmentList *out, ReportId report_id);
static util::Uuid GetJournalId();
static s64 GetMaxReportSize();
static Result GetReportList(ReportList *out, ReportType type_filter);

View File

@@ -77,19 +77,14 @@ namespace ams::erpt::srv {
R_SUCCEED();
}
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());
}
Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) {
u32 count = 0;
for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < max_out_infos; it++) {
for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < util::size(out->attachments); it++) {
if (report_id == it->m_info.owner_report_id) {
out_infos[count++] = it->m_info;
out->attachments[count++] = it->m_info;
}
}
*out_count = count;
out->attachment_count = count;
R_SUCCEED();
}

View File

@@ -86,23 +86,10 @@ namespace ams::erpt::srv {
R_SUCCEED();
}
Result ManagerImpl::GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_list, const ReportId &report_id) {
Result ManagerImpl::GetAttachmentList(const ams::sf::OutBuffer &out_list, const ReportId &report_id) {
R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument());
auto *attachment_list = reinterpret_cast<AttachmentList *>(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<u32> out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id) {
R_RETURN(Journal::GetAttachmentList(out_count.GetPointer(), reinterpret_cast<AttachmentInfo *>(out_buf.GetPointer()), out_buf.GetSize() / sizeof(AttachmentInfo), report_id));
}
Result ManagerImpl::GetReportSizeMax(ams::sf::Out<u32> out) {
/* TODO: Where is this size defined? */
constexpr size_t ReportSizeMax = 0x3FF4F;
*out = ReportSizeMax;
R_SUCCEED();
R_RETURN(Journal::GetAttachmentList(reinterpret_cast<AttachmentList *>(out_list.GetPointer()), report_id));
}
}

View File

@@ -34,9 +34,7 @@ namespace ams::erpt::srv {
Result CleanupReports();
Result DeleteReport(const ReportId &report_id);
Result GetStorageUsageStatistics(ams::sf::Out<StorageUsageStatistics> out);
Result GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
Result GetAttachmentList(ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
Result GetReportSizeMax(ams::sf::Out<u32> out);
Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
};
static_assert(erpt::sf::IsIManager<ManagerImpl>);

View File

@@ -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, const ReportId *specified_report_id) {
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<ContextRecord>();
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, specified_report_id));
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<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> 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);
@@ -444,7 +444,7 @@ namespace ams::erpt::srv {
R_TRY(SubmitReportDefaults(ctx));
/* Generate report id. */
const ReportId report_id = specified_report_id ? *specified_report_id : ReportId{ .uuid = util::GenerateUuid() };
const ReportId report_id = { .uuid = util::GenerateUuid() };
/* Get posix timestamps. */
time::PosixTime timestamp_user;

View File

@@ -58,8 +58,8 @@ namespace ams::erpt::srv {
private:
static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> 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, const ReportId *specified_report_id);
static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, 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, 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<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags);
};
}

View File

@@ -69,7 +69,7 @@ namespace ams::fs {
return GetReference(g_stratosphere_romfs_fs);
}
Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
/* Print a path suitable for the remote service. */
fssrv::sf::Path sf_path;
R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path));
@@ -79,11 +79,7 @@ namespace ams::fs {
R_TRY(fsp->SetCurrentProcess({}));
sf::SharedPointer<fssrv::sf::IFileSystem> fs;
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));
}
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<impl::FileSystemServiceObjectAdapter>(std::move(fs));
@@ -152,7 +148,7 @@ namespace ams::fs {
R_SUCCEED();
}
Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
/* If we can open an sd card code fs, use it. */
R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id)));
@@ -160,7 +156,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, storage_id));
R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id));
}
Result OpenHblCodeFileSystemImpl(std::unique_ptr<fsa::IFileSystem> *out) {
@@ -338,12 +334,11 @@ namespace ams::fs {
util::optional<SdCardRedirectionCodeFileSystem> m_code_fs;
util::optional<ReadOnlyFileSystem> 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, ncm::StorageId storage_id, bool is_hbl, bool is_specific) {
Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) {
AMS_ABORT_UNLESS(!m_initialized);
/* If we're hbl, we need to open a hbl fs. */
@@ -355,11 +350,10 @@ namespace ams::fs {
/* Open the code filesystem. */
std::unique_ptr<fsa::IFileSystem> fsa;
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id, storage_id));
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id));
m_code_fs.emplace(std::move(fsa), program_id, is_specific);
m_program_id = program_id;
m_storage_id = storage_id;
m_program_id = program_id;
m_initialized = true;
R_SUCCEED();
@@ -392,7 +386,7 @@ namespace ams::fs {
}
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
auto mount_impl = [=]() -> Result {
/* Clear the output. */
std::memset(out, 0, sizeof(*out));
@@ -405,7 +399,7 @@ namespace ams::fs {
/* Open the code file system. */
std::unique_ptr<fsa::IFileSystem> fsa;
R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id));
R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id));
/* Register. */
R_RETURN(fsa::Register(name, std::move(fsa)));
@@ -420,7 +414,7 @@ namespace ams::fs {
R_SUCCEED();
}
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 MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) {
auto mount_impl = [=]() -> Result {
/* Clear the output. */
std::memset(out, 0, sizeof(*out));
@@ -436,7 +430,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, storage_id, is_hbl, is_specific));
R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, is_hbl, is_specific));
/* Register. */
R_RETURN(fsa::Register(name, std::move(ams_code_fs)));
@@ -451,7 +445,7 @@ namespace ams::fs {
R_SUCCEED();
}
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
auto mount_impl = [=]() -> Result {
/* Clear the output. */
std::memset(out, 0, sizeof(*out));
@@ -464,7 +458,7 @@ namespace ams::fs {
/* Open the code file system. */
std::unique_ptr<fsa::IFileSystem> fsa;
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id));
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id));
/* Create a wrapper fs. */
auto wrap_fsa = std::make_unique<SdCardRedirectionCodeFileSystem>(std::move(fsa), program_id, false);

View File

@@ -33,7 +33,7 @@ namespace ams::fs {
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
::FsCodeInfo dummy;
::FsFileSystem fs;
R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED();
@@ -41,7 +41,7 @@ namespace ams::fs {
Result OpenCodeFileSystemDeprecated2(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED();
@@ -49,23 +49,15 @@ namespace ams::fs {
Result OpenCodeFileSystemDeprecated3(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> 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, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED();
}
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED();
}
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<u8>(storage_id)), nullptr, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED();

View File

@@ -21,7 +21,7 @@ namespace ams::fs::impl {
#define ADD_ENUM_CASE(v) case v: return #v
template<> const char *IdString::ToString<pkg1::KeyGeneration>(pkg1::KeyGeneration id) {
static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_20_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";
@@ -42,8 +42,7 @@ 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-19.0.1";
case KeyGeneration_20_0_0: return "20.0.0-";
case KeyGeneration_19_0_0: return "19.0.0-";
default: return "Unknown";
}
}

View File

@@ -482,16 +482,11 @@ namespace ams::fssrv {
AMS_UNUSED(out_fs, out_verif, path, attr, program_id);
}
Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> 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<bool> out, u64 process_id) {
AMS_ABORT("TODO");
AMS_UNUSED(out, process_id);

View File

@@ -32,14 +32,8 @@ 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, 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,
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) {
return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);

View File

@@ -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, const LoaderProgramAttributes *attr);
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc);
Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status);
#ifdef __cplusplus

View File

@@ -19,14 +19,13 @@
namespace ams::ldr::pm {
/* Information API. */
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<const ::LoaderProgramAttributes *>(std::addressof(attrs)), out));
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) {
R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, out));
}
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) {
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) {
static_assert(sizeof(*out) == sizeof(LoaderProgramInfo));
R_RETURN(ldrPmGetProgramInfo(reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs)), reinterpret_cast<LoaderProgramInfo *>(out)));
R_RETURN(ldrPmGetProgramInfo(reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<LoaderProgramInfo *>(out)));
}
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) {
@@ -42,10 +41,10 @@ namespace ams::ldr::pm {
R_RETURN(ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast<u64>(program_id)));
}
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) {
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<LoaderProgramInfo *>(out), reinterpret_cast<CfgOverrideStatus *>(out_status), reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs))));
R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast<LoaderProgramInfo *>(out), reinterpret_cast<CfgOverrideStatus *>(out_status), reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc))));
}
Result SetEnabledProgramVerification(bool enabled) {

View File

@@ -534,34 +534,4 @@ namespace ams::ncm {
R_SUCCEED();
}
Result ContentMetaDatabaseImpl::HasAttributes(sf::Out<u8> 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();
}
}

View File

@@ -65,7 +65,6 @@ namespace ams::ncm {
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) override;
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override;
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) override;
virtual Result HasAttributes(sf::Out<u8> out, u8 attr_mask) override;
};
}

View File

@@ -81,7 +81,6 @@ namespace ams::ncm {
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) = 0;
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0;
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) = 0;
virtual Result HasAttributes(sf::Out<u8> out, u8 attr_mask) = 0;
};
static_assert(ncm::IsIContentMetaDatabase<ContentMetaDatabaseImplBase>);

View File

@@ -463,28 +463,4 @@ namespace ams::ncm {
}));
}
Result IntegratedContentMetaDatabaseImpl::HasAttributes(sf::Out<u8> 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();
}
}

View File

@@ -191,12 +191,6 @@ namespace ams::ncm {
static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8));
R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast<u8 *>(out.GetPointer()), Convert(key)));
}
Result HasAttributes(sf::Out<u8> out, u8 attr_mask) {
/* TODO: libnx bindings */
AMS_UNUSED(out, attr_mask);
AMS_ABORT();
}
};
static_assert(ncm::IsIContentMetaDatabase<RemoteContentMetaDatabaseImpl>);
#endif

View File

@@ -43,7 +43,6 @@ 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;

View File

@@ -16,11 +16,11 @@
#pragma once
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
#define ATMOSPHERE_RELEASE_VERSION_MINOR 9
#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 20
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 19
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0

View File

@@ -81,14 +81,10 @@
#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_1
#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
@@ -162,12 +158,8 @@ 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,

View File

@@ -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(InvalidProgramAttributes, 14);
R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14);
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51);
R_DEFINE_ERROR_RESULT(InvalidNroImage, 52);

View File

@@ -112,14 +112,6 @@ _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
@@ -154,15 +146,11 @@ _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. */
@@ -176,7 +164,6 @@ _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. */
@@ -233,14 +220,6 @@ _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
@@ -262,7 +241,6 @@ _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)]
@@ -287,9 +265,6 @@ _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
@@ -413,6 +388,14 @@ _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 */
@@ -430,44 +413,27 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv:
mov x30, x22
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::FlushEntireDataCacheLocalWithoutStack() */
@@ -509,27 +475,44 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv:
mov x30, x24
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::FlushEntireDataCacheImplWithoutStack() */

View File

@@ -354,12 +354,21 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv:
mrs x17, ttbr0_el1
and x17, x17, #(0xFFFF << 48)
/* Invalidate the address held by FAR (and assume it is valid). */
/* 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. */
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
@@ -476,16 +485,33 @@ _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
/* Invalidate the address held by FAR (and assume it is valid). */
/* 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. */
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

View File

@@ -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 = 12_MB;
constexpr size_t MallocBufferSize = 32_MB;
alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
}

View File

@@ -17,7 +17,6 @@
#include "../amsmitm_fs_utils.hpp"
#include "fsmitm_romfs.hpp"
#include "fsmitm_layered_romfs_storage.hpp"
#include "memlet/memlet.h"
namespace ams::mitm::fs {
@@ -27,8 +26,6 @@ namespace ams::mitm::fs {
namespace {
constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB;
struct ApplicationWithDynamicHeapInfo {
ncm::ProgramId program_id;
size_t dynamic_app_heap_size;
@@ -44,7 +41,7 @@ namespace ams::mitm::fs {
/* Fire Emblem: Engage. */
/* Requirement ~32+ MB. */
/* No particular heap sensitivity. */
{ 0x0100A6301214E000, 20_MB, 0_MB },
{ 0x0100A6301214E000, 16_MB, 0_MB },
/* The Legend of Zelda: Tears of the Kingdom. */
/* Requirement ~48 MB. */
@@ -88,12 +85,10 @@ 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 || this->heap_size == 0);
AMS_ABORT_UNLESS(this->heap_address != 0);
/* Create heap. */
if (this->heap_size > 0) {
util::ConstructAt(this->heap, reinterpret_cast<void *>(this->heap_address), this->heap_size);
}
util::ConstructAt(this->heap, reinterpret_cast<void *>(this->heap_address), this->heap_size);
}
}
@@ -161,52 +156,6 @@ 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<uintptr_t>(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{};
@@ -215,7 +164,6 @@ namespace ams::mitm::fs {
constinit DynamicHeap<os::AllocateUnsafeMemory, os::FreeUnsafeMemory> g_dynamic_app_heap;
constinit DynamicHeap<MapByHeap, UnmapByHeap> g_dynamic_sys_heap;
constinit DynamicHeap<MapAppletMemory, UnmapAppletMemory> 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) {
@@ -227,10 +175,6 @@ 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();
}
}
}
@@ -239,33 +183,15 @@ 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) {
if (g_building_from_dynamic_heap) {
void *ret = nullptr;
if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) {
ret = g_dynamic_let_heap.Allocate(size);
}
AMS_UNUSED(type);
if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) {
ret = g_dynamic_app_heap.Allocate(size);
}
if (g_building_from_dynamic_heap) {
void *ret = g_dynamic_app_heap.Allocate(size);
if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) {
ret = g_dynamic_sys_heap.Allocate(size);
@@ -285,11 +211,7 @@ namespace ams::mitm::fs {
AMS_UNUSED(type);
AMS_UNUSED(size);
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_dynamic_app_heap.TryFree(p)) {
if (!g_building_from_dynamic_heap) {
g_dynamic_app_heap.TryRelease();
}
@@ -1099,7 +1021,6 @@ 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;

View File

@@ -1,41 +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 <http://www.gnu.org/licenses/>.
*/
#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,
);
}

View File

@@ -1,32 +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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#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

View File

@@ -1,65 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <switch/types.h>
#include <switch/result.h>
#include <switch/kernel/mutex.h>
#include <switch/sf/service.h>
#include <switch/services/sm.h>
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

View File

@@ -25,12 +25,12 @@ namespace ams::ldr {
}
/* ScopedCodeMount functionality. */
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, 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, 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(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() {
@@ -46,28 +46,28 @@ namespace ams::ldr {
}
}
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) {
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform 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, attrs));
R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform));
/* Get the content attributes. */
const auto content_attributes = attrs.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, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_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, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_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, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_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;
}
@@ -83,7 +83,7 @@ namespace ams::ldr {
}
/* Redirection API. */
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) {
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) {
/* Check for storage id none. */
if (static_cast<ncm::StorageId>(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 = attrs.content_attributes;
const auto content_attributes = GetPlatformContentAttributes(platform);
AMS_UNUSED(content_attributes);
lr::Path path;
@@ -166,4 +166,12 @@ 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();
}
}
}

View File

@@ -34,8 +34,8 @@ namespace ams::ldr {
bool m_mounted_sd_or_code;
bool m_mounted_code;
public:
ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs);
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs);
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, const ldr::ProgramAttributes &attrs);
Result Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform);
void EnsureOverrideStatus(const ncm::ProgramLocation &loc);
};
@@ -76,8 +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, const ldr::ProgramAttributes &attrs);
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(ncm::ContentMetaPlatform platform);
}

View File

@@ -69,11 +69,6 @@ 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 },
@@ -87,5 +82,4 @@ 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 */
};

View File

@@ -27,72 +27,72 @@ namespace ams::ldr {
constinit ArgumentStore g_argument_store;
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;
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<ncm::StorageId>(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));
}
}
return true;
/* 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, 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::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::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<ncm::StorageId>(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::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, ncm::ContentMetaPlatform::Nx));
}
Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {

View File

@@ -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, const ProgramAttributes &attrs) {
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h) {
/* 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(), attrs));
R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle()));
}
Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) {
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc, attrs));
Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc) {
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc));
}
Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc) {
@@ -75,16 +75,16 @@ namespace ams::ldr {
return this->HasLaunchedBootProgram(out.GetPointer(), program_id);
}
Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) {
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc, attrs));
Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc) {
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc));
}
Result AtmospherePinProgram(sf::Out<PinId> 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, const ProgramAttributes &attrs);
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs);
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 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);

View File

@@ -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, const ldr::ProgramAttributes &attrs) {
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, attrs);
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, attrs.platform));
R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, 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, const ldr::ProgramAttributes &attrs) {
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform) {
Meta meta;
/* Load Meta. */
{
AMS_UNUSED(path);
ScopedCodeMount mount(loc, attrs);
ScopedCodeMount mount(loc, platform);
R_TRY(mount.GetResult());
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), attrs.platform, false));
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false));
if (out_status != nullptr) {
*out_status = mount.GetOverrideStatus();
}

View File

@@ -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, const ldr::ProgramAttributes &attrs);
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs);
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);

View File

@@ -1,41 +0,0 @@
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))

View File

@@ -1,93 +0,0 @@
{
"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
}]
}

View File

@@ -1,75 +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 <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#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<NumServers, ServerOptions, NumSessions> g_server_manager;
constinit sf::UnmanagedServiceObject<memlet::impl::IService, memlet::Service> 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();
}
}

View File

@@ -1,58 +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 <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "memlet_service.hpp"
namespace ams::memlet {
Result Service::CreateAppletSharedMemory(sf::Out<u64> 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();
}
}

View File

@@ -1,32 +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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
#define AMS_MEMLET_I_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 65000, Result, CreateAppletSharedMemory, (sf::Out<u64> 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<u64> out_size, sf::OutMoveHandle out_handle, u64 desired_size);
};
static_assert(impl::IsIService<Service>);
}

Some files were not shown because too many files have changed in this diff Show More