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: 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. * 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 * 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 * 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 * 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/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/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/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/daybreak/daybreak.elf $(DIST_DIR)/daybreak.elf
cp $(CURRENT_DIRECTORY)/troposphere/haze/haze.elf $(DIST_DIR)/haze.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 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/010000000000003c
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 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/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/010000000000b240
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623 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/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/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/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 @build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs
rm -r $(DIST_DIR)/stratosphere_romfs rm -r $(DIST_DIR)/stratosphere_romfs
cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro

View File

@@ -1,29 +1,4 @@
# Changelog # 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 ## 1.8.0
+ Basic support was added for 19.0.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. + 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*** *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions ### Supported Horizon Versions
**1.0.0 - 20.0.0** **1.0.0 - 19.0.0**
## Features ## Features
* Arbitrary SDMMC backend selection * Arbitrary SDMMC backend selection

View File

@@ -75,8 +75,6 @@
#include "offsets/1810_exfat.h" #include "offsets/1810_exfat.h"
#include "offsets/1900.h" #include "offsets/1900.h"
#include "offsets/1900_exfat.h" #include "offsets/1900_exfat.h"
#include "offsets/2000.h"
#include "offsets/2000_exfat.h"
#include "../utils/fatal.h" #include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -163,8 +161,6 @@ DEFINE_OFFSET_STRUCT(_1810);
DEFINE_OFFSET_STRUCT(_1810_EXFAT); DEFINE_OFFSET_STRUCT(_1810_EXFAT);
DEFINE_OFFSET_STRUCT(_1900); DEFINE_OFFSET_STRUCT(_1900);
DEFINE_OFFSET_STRUCT(_1900_EXFAT); 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) { const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) { switch (version) {
@@ -286,10 +282,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1900)); return &(GET_OFFSET_STRUCT_NAME(_1900));
case FS_VER_19_0_0_EXFAT: case FS_VER_19_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1900_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: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -110,9 +110,6 @@ enum FS_VER
FS_VER_19_0_0, FS_VER_19_0_0,
FS_VER_19_0_0_EXFAT, FS_VER_19_0_0_EXFAT,
FS_VER_20_0_0,
FS_VER_20_0_0_EXFAT,
FS_VER_MAX, 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. */ /* 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. */ /* TODO: Update on next change of keys. */
/* Mariko Development Master Kek Source. */ /* 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. */ /* 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. */ /* 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. */ .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 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 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 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. */ /* 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. */ .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 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 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 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. */ /* 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. */ .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 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 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 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. */ /* 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. */ .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 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 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 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. */ /* 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. */ .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 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 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 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. */ /* 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) { if (key_generation >= pkg1::KeyGeneration_Count) {
return false; return false;
} }

View File

@@ -23,17 +23,17 @@ namespace ams::nxboot {
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */ /* 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] = { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */ /* 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] = { alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */ /* 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] = { 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. */ { 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. */ { 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. */ { 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] = { 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. */ { 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. */ { 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. */ { 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] = { 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. */ { 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. */ { 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. */ { 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] = { 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. */ { 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. */ { 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. */ { 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] = { 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. */ { 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. */ { 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. */ { 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] = {}; 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. */ /* 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) { if (key_generation >= pkg1::KeyGeneration_Count) {
return false; return false;
} }

View File

@@ -263,8 +263,6 @@ namespace ams::nxboot {
return ams::TargetFirmware_18_0_0; return ams::TargetFirmware_18_0_0;
} else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) { } else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) {
return ams::TargetFirmware_19_0_0; return ams::TargetFirmware_19_0_0;
} else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) {
return ams::TargetFirmware_20_0_0;
} }
break; break;
default: default:

View File

@@ -180,9 +180,6 @@ namespace ams::nxboot {
FsVersion_19_0_0, FsVersion_19_0_0,
FsVersion_19_0_0_Exfat, FsVersion_19_0_0_Exfat,
FsVersion_20_0_0,
FsVersion_20_0_0_Exfat,
FsVersion_Count, FsVersion_Count,
}; };
@@ -275,9 +272,6 @@ namespace ams::nxboot {
{ 0xD9, 0x4C, 0x68, 0x15, 0xF8, 0xF5, 0x0A, 0x20 }, /* FsVersion_19_0_0 */ { 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 */ { 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) { 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, 0x1A16A5, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1)); AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1));
break; 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: default:
break; break;
} }

View File

@@ -39,7 +39,6 @@ namespace ams::pkg1 {
KeyGeneration_17_0_0 = 0x10, KeyGeneration_17_0_0 = 0x10,
KeyGeneration_18_0_0 = 0x11, KeyGeneration_18_0_0 = 0x11,
KeyGeneration_19_0_0 = 0x12, KeyGeneration_19_0_0 = 0x12,
KeyGeneration_20_0_0 = 0x13,
KeyGeneration_Count, KeyGeneration_Count,

View File

@@ -24,7 +24,7 @@ namespace ams::pkg2 {
constexpr inline int PayloadCount = 3; 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 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 { struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>; using Magic = util::FourCC<'P','K','2','1'>;

View File

@@ -177,7 +177,6 @@ namespace ams::fuse {
} }
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_20_0_0,
TargetFirmware_19_0_0, TargetFirmware_19_0_0,
TargetFirmware_17_0_0, TargetFirmware_17_0_0,
TargetFirmware_16_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 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); 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(); Result Finalize();
static void NoteUpdatedCallback(const void *pt) {
/* Note the update. */
static_cast<const KPageTable *>(pt)->NoteUpdated();
}
private: private:
Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll); 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; EntryLevel level;
bool is_contiguous; bool is_contiguous;
}; };
using EntryUpdatedCallback = void (*)(const void *);
private: private:
static constexpr size_t PageBits = util::CountTrailingZeros(PageSize); static constexpr size_t PageBits = util::CountTrailingZeros(PageSize);
static constexpr size_t NumLevels = 3; static constexpr size_t NumLevels = 3;
@@ -146,8 +144,8 @@ namespace ams::kern::arch::arm64 {
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const; bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const;
static bool MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt); static bool MergePages(KVirtualAddress *out, TraversalContext *context);
void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const; void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const;
KProcessAddress GetAddressForContext(const TraversalContext *context) const { KProcessAddress GetAddressForContext(const TraversalContext *context) const {
KProcessAddress addr = m_is_kernel ? static_cast<uintptr_t>(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0; 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 { class UserspaceAccess {
private: private:
class Impl { static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src);
public:
static bool CopyMemoryFromUser(void *dst, const void *src, size_t size);
static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size);
static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size);
static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src);
static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src);
static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src);
static s32 CopyStringFromUser(void *dst, const void *src, size_t size);
static bool CopyMemoryToUser(void *dst, const void *src, size_t size);
static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size);
static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size);
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src);
static s32 CopyStringToUser(void *dst, const void *src, size_t size);
static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask);
static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value);
static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare);
static bool StoreDataCache(uintptr_t start, uintptr_t end);
static bool FlushDataCache(uintptr_t start, uintptr_t end);
static bool InvalidateDataCache(uintptr_t start, uintptr_t end);
static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size);
static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size);
static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size);
static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size);
static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size);
static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size);
};
public: 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) { static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) {
/* Check that the address is within the valid userspace range. */ /* 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) { 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 false;
} }
return Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(dst, src); return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src);
} }
static s32 CopyStringFromUser(void *dst, const void *src, size_t size) { static bool CopyMemoryFromUser(void *dst, const void *src, size_t size);
return Impl::CopyStringFromUser(dst, src, 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) { static bool CopyMemoryToUser(void *dst, const void *src, size_t size);
return Impl::CopyMemoryToUser(dst, src, 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) { static bool ClearMemory(void *dst, size_t size);
return Impl::CopyMemoryToUserAligned32Bit(dst, src, 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) { static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask);
return Impl::CopyMemoryToUserAligned64Bit(dst, src, size); 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) { static bool StoreDataCache(uintptr_t start, uintptr_t end);
return Impl::CopyMemoryToUserSize32Bit(dst, src); 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) { static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size);
return Impl::CopyStringToUser(dst, src, 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 UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) { static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size);
return Impl::UpdateLockAtomic(out, address, if_zero, new_orr_mask); static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size);
}
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);
}
}; };

View File

@@ -37,7 +37,7 @@ namespace ams::kern {
size_t m_size; size_t m_size;
Type m_type; Type m_type;
public: 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 size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type);
static void SetAddressSpaceSize(size_t width, Type type, size_t size); 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); Result Initialize(KProcessAddress st, KProcessAddress nd, KMemoryBlockSlabManager *slab_manager);
void Finalize(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; 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); 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. */ /* Nintendo uses std::mt19937_t for randomness. */
/* To save space (and because mt19337_t isn't secure anyway), */ /* To save space (and because mt19337_t isn't secure anyway), */
/* We will use TinyMT. */ /* 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 util::TinyMT s_random_generator{util::ConstantInitialize};
static constinit inline KSpinLock s_random_lock; static constinit inline KSpinLock s_random_lock;
public: public:

View File

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

View File

@@ -25,35 +25,35 @@ namespace ams::kern {
friend class KSystemControl; friend class KSystemControl;
private: private:
struct KTargetSystemData { struct KTargetSystemData {
bool is_not_debug_mode; bool is_debug_mode;
bool disable_debug_logging; bool enable_debug_logging;
bool disable_user_exception_handlers; bool enable_user_exception_handlers;
bool disable_debug_memory_fill; bool enable_debug_memory_fill;
bool disable_user_pmu_access; bool enable_user_pmu_access;
bool disable_kernel_debugging; bool enable_kernel_debugging;
bool disable_dynamic_resource_limits; bool enable_dynamic_resource_limits;
}; };
private: 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 = { static inline constinit const volatile KTargetSystemData s_data = {
.is_not_debug_mode = false, .is_debug_mode = true,
.disable_debug_logging = false, .enable_debug_logging = true,
.disable_user_exception_handlers = false, .enable_user_exception_handlers = true,
.disable_debug_memory_fill = false, .enable_debug_memory_fill = true,
.disable_user_pmu_access = false, .enable_user_pmu_access = true,
.disable_kernel_debugging = false, .enable_kernel_debugging = true,
.disable_dynamic_resource_limits = true, .enable_dynamic_resource_limits = false,
}; };
private: private:
static ALWAYS_INLINE void SetInitialized() { s_is_uninitialized = false; } static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; }
public: public:
static ALWAYS_INLINE bool IsDebugMode() { return !(s_is_uninitialized | s_data.is_not_debug_mode); } static ALWAYS_INLINE bool IsDebugMode() { return s_is_initialized && s_data.is_debug_mode; }
static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return !(s_is_uninitialized | s_data.disable_debug_logging); } static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_is_initialized && s_data.enable_debug_logging; }
static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return !(s_is_uninitialized | s_data.disable_user_exception_handlers); } static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_is_initialized && s_data.enable_user_exception_handlers; }
static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return !(s_is_uninitialized | s_data.disable_debug_memory_fill); } static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_is_initialized && s_data.enable_debug_memory_fill; }
static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return !(s_is_uninitialized | s_data.disable_user_pmu_access); } static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_is_initialized && s_data.enable_user_pmu_access; }
static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return !(s_is_uninitialized | s_data.disable_kernel_debugging); } static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_is_initialized && s_data.enable_kernel_debugging; }
static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return !(s_is_uninitialized | s_data.disable_dynamic_resource_limits); } 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; return insn;
} }
void HandleUserException(KExceptionContext *context, u64 raw_esr, u64 raw_far, u64 afsr0, u64 afsr1, u32 data) { void HandleUserException(KExceptionContext *context, u64 esr, u64 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;
}
}
}
KProcess &cur_process = GetCurrentProcess(); KProcess &cur_process = GetCurrentProcess();
bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled(); 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. */ /* 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) #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
context->psr |= (1ul << 21); context->psr |= (1ul << 21);
@@ -184,7 +165,7 @@ namespace ams::kern::arch::arm64 {
} }
/* Save the debug parameters to the current thread. */ /* Save the debug parameters to the current thread. */
GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data); GetCurrentThread().SaveDebugParams(far, esr, data);
/* Get the exception type. */ /* Get the exception type. */
u32 type; u32 type;
@@ -406,6 +387,7 @@ namespace ams::kern::arch::arm64 {
ams::svc::aarch32::ExceptionInfo info32; ams::svc::aarch32::ExceptionInfo info32;
} info = {}; } info = {};
const bool is_aarch64 = (e_ctx->psr & 0x10) == 0; const bool is_aarch64 = (e_ctx->psr & 0x10) == 0;
if (is_aarch64) { if (is_aarch64) {
/* We're 64-bit. */ /* We're 64-bit. */
@@ -450,28 +432,9 @@ namespace ams::kern::arch::arm64 {
uintptr_t far, esr, data; uintptr_t far, esr, data;
GetCurrentThread().RestoreDebugParams(std::addressof(far), std::addressof(esr), std::addressof(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. */ /* Collect additional information based on the ec. */
uintptr_t params[3] = {}; uintptr_t params[3] = {};
switch (ec) { switch ((esr >> 26) & 0x3F) {
case EsrEc_Unknown: case EsrEc_Unknown:
case EsrEc_IllegalExecution: case EsrEc_IllegalExecution:
case EsrEc_BkptInstruction: case EsrEc_BkptInstruction:

View File

@@ -752,10 +752,13 @@ namespace ams::kern::arch::arm64 {
while (true) { while (true) {
/* Try to merge. */ /* Try to merge. */
KVirtualAddress freed_table = Null<KVirtualAddress>; 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; break;
} }
/* Note that we updated. */
this->NoteUpdated();
/* Free the page. */ /* Free the page. */
if (freed_table != Null<KVirtualAddress>) { if (freed_table != Null<KVirtualAddress>) {
ClearPageTable(freed_table); ClearPageTable(freed_table);
@@ -813,7 +816,8 @@ namespace ams::kern::arch::arm64 {
} }
/* Separate. */ /* 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(); 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). */ /* 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); 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. */ /* We've succeeded, now perform what coalescing we can. */

View File

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

View File

@@ -361,9 +361,7 @@ namespace ams::kern::board::nintendo::nx {
}(); }();
/* Return (possibly) adjusted size. */ /* Return (possibly) adjusted size. */
/* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */ constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB;
/* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
} }
@@ -407,22 +405,22 @@ namespace ams::kern::board::nintendo::nx {
/* Configure KTargetSystem. */ /* Configure KTargetSystem. */
volatile auto *ts = const_cast<volatile KTargetSystem::KTargetSystemData *>(std::addressof(KTargetSystem::s_data)); 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. */ /* If debug mode, we want to initialize uart logging. */
ts->disable_debug_logging = ts->is_not_debug_mode; ts->enable_debug_logging = ts->is_debug_mode;
} }
/* Set Kernel Configuration. */ /* Set Kernel Configuration. */
{ {
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
ts->disable_debug_memory_fill = !kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>(); ts->enable_debug_memory_fill = kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
ts->disable_user_exception_handlers = !kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>(); ts->enable_user_exception_handlers = kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
ts->disable_dynamic_resource_limits = kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>(); ts->enable_dynamic_resource_limits = !kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
ts->disable_user_pmu_access = !kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>(); ts->enable_user_pmu_access = kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
/* Configure call smc on panic. */ /* Configure call smc on panic. */
*const_cast<volatile bool *>(std::addressof(g_call_smc_on_panic)) = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>(); *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. */ /* 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. */ /* 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); 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(); }); return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); });
} else { } else {
return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc); return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc);
@@ -537,7 +535,7 @@ namespace ams::kern::board::nintendo::nx {
KScopedInterruptDisable intr_disable; KScopedInterruptDisable intr_disable;
KScopedSpinLock lk(s_random_lock); KScopedSpinLock lk(s_random_lock);
if (AMS_LIKELY(!s_uninitialized_random_generator)) { if (AMS_LIKELY(s_initialized_random_generator)) {
return s_random_generator.GenerateRandomU64(); return s_random_generator.GenerateRandomU64();
} else { } else {
return GenerateRandomU64FromSmc(); 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) { uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
MESOSPHERE_UNUSED(code_size);
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress(); return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress();
} }
size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
/* Extract the address space from the create process flags. */ return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize();
const auto as_flags = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
/* Get the address space width. */
const auto as_width = GetAddressSpaceWidth(flags);
/* Get the size. */
size_t as_size = GetAddressSpaceInfo(as_width, type).GetSize();
/* If we're getting size for 32-bit without alias, adjust the sizes accordingly. */
if (as_flags == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) {
switch (type) {
/* The heap space receives space that would otherwise go to the alias space. */
case KAddressSpaceInfo::Type_Heap:
as_size += GetAddressSpaceInfo(as_width, KAddressSpaceInfo::Type_Alias).GetSize();
break;
/* The alias space doesn't exist. */
case KAddressSpaceInfo::Type_Alias:
as_size = 0;
break;
/* Nothing to do by default. */
default:
break;
}
}
return as_size;
} }
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) { 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; out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge;
/* Set and check code address. */ /* 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; 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 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 size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
const uintptr_t map_end = map_start + map_size; const uintptr_t map_end = map_start + map_size;
out->code_address = map_start + start_address; out->code_address = map_start + start_address;

View File

@@ -118,78 +118,29 @@ namespace ams::kern {
MESOSPHERE_ASSERT(m_memory_block_tree.empty()); 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 { 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. */ if (num_pages > 0) {
KProcessAddress search_start = Null<KProcessAddress>; const KProcessAddress region_end = region_start + region_num_pages * PageSize;
KProcessAddress search_end = Null<KProcessAddress>; const KProcessAddress region_last = region_end - 1;
if (this->GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) { for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) {
/* Iterate over blocks in the search space, looking for a suitable one. */ if (region_last < it->GetAddress()) {
for (const_iterator it = this->FindIterator(search_start); it != m_memory_block_tree.cend(); it++) {
/* If our block is past the end of our search space, we're done. */
if (search_end < it->GetAddress()) {
break; break;
} }
/* We only want to consider free blocks. */
if (it->GetState() != KMemoryState_Free) { if (it->GetState() != KMemoryState_Free) {
continue; continue;
} }
/* Determine the candidate range. */ KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress();
KProcessAddress candidate_start = Null<KProcessAddress>; area += guard_pages * PageSize;
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;
}
/* Try the suggested candidate (coercing into the search region if needed). */ const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset;
KProcessAddress candidate = candidate_start; area = (area <= offset_area) ? offset_area : offset_area + alignment;
if (candidate < search_start) {
candidate = search_start;
}
/* Check if the candidate is valid. */ const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize;
if (candidate <= search_end && candidate <= candidate_end) { const KProcessAddress area_last = area_end - 1;
return candidate;
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. */ /* Define helpers. */
auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { 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 { auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
return KAddressSpaceInfo::GetAddressSpaceSize(flags, type); return KAddressSpaceInfo::GetAddressSpaceSize(flags, type);
@@ -155,6 +155,12 @@ namespace ams::kern {
size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias);
size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); 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. */ /* Set code regions and determine remaining sizes. */
KProcessAddress process_code_start; KProcessAddress process_code_start;
KProcessAddress process_code_end; 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 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 address = Null<KProcessAddress>;
KProcessAddress search_start = Null<KProcessAddress>; if (num_pages <= region_num_pages) {
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 (this->IsAslrEnabled()) { if (this->IsAslrEnabled()) {
/* Try to directly find a free area up to 8 times. */ /* Try to directly find a free area up to 8 times. */
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
const size_t random_offset = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment) * alignment; const size_t random_offset = KSystemControl::GenerateRandomRange(0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) * alignment;
const KProcessAddress candidate = search_start + random_offset; const KProcessAddress candidate = util::AlignDown(GetInteger(region_start + random_offset), alignment) + offset;
KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate); KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate);
MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end()); MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end());
if (it->GetState() != KMemoryState_Free) { continue; } if (it->GetState() != KMemoryState_Free) { continue; }
if (!(region_start <= candidate)) { continue; }
if (!(it->GetAddress() + guard_pages * PageSize <= GetInteger(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 <= it->GetLastAddress())) { continue; }
if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= region_start + region_num_pages * PageSize - 1)) { continue; }
address = candidate; address = candidate;
break; break;
} }
/* Fall back to finding the first free area with a random offset. */ /* Fall back to finding the first free area with a random offset. */
if (address == Null<KProcessAddress>) { if (address == Null<KProcessAddress>) {
/* NOTE: Nintendo does not account for guard pages here. */ /* NOTE: Nintendo does not account for guard pages here. */
/* This may theoretically cause an offset to be chosen that cannot be mapped. */ /* This may theoretically cause an offset to be chosen that cannot be mapped. */
/* We will account for guard pages. */ /* We will account for guard pages. */
const size_t offset_blocks = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment); const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages);
const auto region_end = region_start + region_num_pages * PageSize; address = m_memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages);
address = m_memory_block_manager.FindFreeArea(search_start + offset_blocks * alignment, (region_end - (search_start + offset_blocks * alignment)) / PageSize, num_pages, alignment, offset, guard_pages);
} }
} }
/* Find the first free area. */ /* Find the first free area. */
if (address == Null<KProcessAddress>) { if (address == Null<KProcessAddress>) {
address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages, alignment, offset, guard_pages); 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; 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. */ /* Perform mapping operation. */
const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; 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)); R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, operation, false));
/* Update the blocks. */ /* Update the blocks. */
m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); 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. */ /* 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(); cpu::InvalidateEntireInstructionCache();
} }
@@ -2548,11 +2546,6 @@ namespace ams::kern {
/* We're going to perform an update, so create a helper. */ /* We're going to perform an update, so create a helper. */
KScopedPageTableUpdater updater(this); KScopedPageTableUpdater updater(this);
/* Ensure cache coherency, if we're mapping executable pages. */
if ((perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) {
cpu::InvalidateEntireInstructionCache();
}
/* Perform mapping operation. */ /* Perform mapping operation. */
const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead };
R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
@@ -2576,9 +2569,8 @@ namespace ams::kern {
KScopedLightLock lk(m_general_lock); KScopedLightLock lk(m_general_lock);
/* Check if state allows us to unmap. */ /* Check if state allows us to unmap. */
KMemoryPermission old_perm;
size_t num_allocator_blocks; 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. */ /* Check that the page group is valid. */
R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), svc::ResultInvalidCurrentMemory()); 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 }; 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)); 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. */ /* Update the blocks. */
m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal); 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. */ /* 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. */ /* Generate random entropy. */
KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy));

View File

@@ -102,10 +102,10 @@ namespace ams::kern {
/* Randomness for Initialization. */ /* Randomness for Initialization. */
void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) { 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(); const u64 seed = KHardwareTimer::GetTick();
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32)); 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) { for (size_t i = 0; i < count; ++i) {
@@ -114,10 +114,10 @@ namespace ams::kern {
} }
u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) { 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(); const u64 seed = KHardwareTimer::GetTick();
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32)); 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(); }); 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) { void KSystemControlBase::InitializePhase1Base(u64 seed) {
/* Initialize the rng, if we somehow haven't already. */ /* 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_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. */ /* Initialize debug logging. */

View File

@@ -59,9 +59,7 @@ namespace ams::kern {
memory_reservation.Commit(); memory_reservation.Commit();
/* Open reference to our resource limit. */ /* Open reference to our resource limit. */
if (m_resource_limit != nullptr) { m_resource_limit->Open();
m_resource_limit->Open();
}
/* Set ourselves as initialized. */ /* Set ourselves as initialized. */
m_is_initialized = true; m_is_initialized = true;
@@ -78,14 +76,11 @@ namespace ams::kern {
/* Free our secure memory. */ /* Free our secure memory. */
KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool); KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool);
/* Clean up our resource usage. */ /* Release the memory reservation. */
if (m_resource_limit != nullptr) { 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. */ /* Close reference to our resource limit. */
m_resource_limit->Close(); m_resource_limit->Close();
}
} }
size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool) { 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); MESOSPHERE_ABORT_UNLESS(rc_size < size);
size -= rc_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. */ /* Initialize the resource managers' shared page manager. */
g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize)); g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
/* Initialize the KPageBuffer slab heap. */ /* Initialize the KPageBuffer slab heap. */
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager); KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);
/* Initialize the block info heap. */ /* Initialize the fixed-size slabheaps. */
s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize);
/* Initialize the system slab managers. */
s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap));
s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize);
s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap));
/* Initialize the application slab managers. */
s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap));
s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize); s_app_memory_block_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. */ /* 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; 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)); 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. */ /* Setup the slab managers. */
s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap)); KDynamicPageManager * const app_dynamic_page_manager = nullptr;
KAutoObject::Create<KSystemResource>(std::addressof(s_sys_system_resource)); KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager); 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)); 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_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap));
s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager);
/* Check that we have the correct number of dynamic pages available. */ /* 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); 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() { void Kernel::PrintLayout() {

View File

@@ -109,12 +109,11 @@ namespace ams::kern::svc {
/* Decide on an address space map region. */ /* Decide on an address space map region. */
uintptr_t map_start, map_end; uintptr_t map_start, map_end;
size_t map_size; size_t map_size;
const size_t code_size = params.code_num_pages * PageSize;
switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) { switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) {
case ams::svc::CreateProcessFlag_AddressSpace32Bit: case ams::svc::CreateProcessFlag_AddressSpace32Bit:
case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: 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_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_end = map_start + map_size; map_end = map_start + map_size;
} }
@@ -124,7 +123,7 @@ namespace ams::kern::svc {
/* 64-bit address space requires 64-bit process. */ /* 64-bit address space requires 64-bit process. */
R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); 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_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
map_end = map_start + map_size; map_end = map_start + map_size;
} }
@@ -134,7 +133,7 @@ namespace ams::kern::svc {
/* 64-bit address space requires 64-bit process. */ /* 64-bit address space requires 64-bit process. */
R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); 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_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); 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 code_num_pages = params.code_num_pages;
const size_t system_resource_num_pages = params.system_resource_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 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 system_resource_size = system_resource_num_pages * PageSize;
const size_t total_size = code_size + system_resource_size; 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, FileServerHtcsServer);
AMS_DEFINE_SYSTEM_THREAD(21, TioServer, SdCardObserver); AMS_DEFINE_SYSTEM_THREAD(21, TioServer, SdCardObserver);
AMS_DEFINE_SYSTEM_THREAD(16, memlet, Main);
/* ServiceProfile */ /* ServiceProfile */
AMS_DEFINE_SYSTEM_THREAD(-1, sprofile, IpcServer); AMS_DEFINE_SYSTEM_THREAD(-1, sprofile, IpcServer);

View File

@@ -181,13 +181,6 @@
HANDLER(NANDTypeInfoDeprecated, 140 ) \ HANDLER(NANDTypeInfoDeprecated, 140 ) \
HANDLER(MicroSDTypeInfo, 141 ) \ HANDLER(MicroSDTypeInfo, 141 ) \
HANDLER(AttachmentFileInfo, 142 ) \ 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(TestNx, 1000) \
HANDLER(NANDTypeInfo, 1001) \ HANDLER(NANDTypeInfo, 1001) \
HANDLER(NANDExtendedCsd, 1002) \ HANDLER(NANDExtendedCsd, 1002) \
@@ -349,7 +342,7 @@
HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(CurrentFanDuty, 155, 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(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(CradleMcuFwVersion, 159, 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(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, 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(CpuDvfsTableClocksDeprecated, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
@@ -463,8 +456,8 @@
HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(EmcDvfsTableVoltagesDeprecated, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(EmcDvfsTableVoltagesDeprecated, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(ModuleClockEnableFlagsDeprecated, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModulePowerEnableFlagsDeprecated, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
@@ -733,7 +726,7 @@
HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(EncryptedDyingMessage, 539, 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(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \
HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
@@ -888,44 +881,6 @@
HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, 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(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \
HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ChargeConfiguration, 1002, 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(BluetoothLePairingInfoCount, 1025, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None )
HANDLER(OscillatorClock, 1029, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(DramId, 1030, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \

View File

@@ -20,28 +20,26 @@
#include <stratosphere/erpt/erpt_multiple_category_context.hpp> #include <stratosphere/erpt/erpt_multiple_category_context.hpp>
#include <stratosphere/time/time_steady_clock_time_point.hpp> #include <stratosphere/time/time_steady_clock_time_point.hpp>
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ #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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_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, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_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, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), 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, 30, Result, InvalidateForcedShutdownDetection, (), (), 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) 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 <vapours.hpp>
#include <stratosphere/erpt/erpt_types.hpp> #include <stratosphere/erpt/erpt_types.hpp>
#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \ #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, 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, 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, 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, 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, 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, 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_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)
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F) AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F)

View File

@@ -21,9 +21,9 @@
namespace ams::fs { namespace ams::fs {
/* ACCURATE_TO_VERSION: 16.2.0.0 */ /* 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 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, ncm::StorageId storage_id); 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 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 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 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, 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 IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id); Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id);
}; };
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>); static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
@@ -175,16 +174,11 @@ namespace ams::fssrv {
R_THROW(fs::ResultPortAcceptableCountLimited()); 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); AMS_UNUSED(out_fs, out_verif, path, attr, program_id);
R_THROW(fs::ResultPortAcceptableCountLimited()); 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) { Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
AMS_UNUSED(out, process_id); AMS_UNUSED(out, process_id);
R_THROW(fs::ResultPortAcceptableCountLimited()); R_THROW(fs::ResultPortAcceptableCountLimited());

View File

@@ -21,13 +21,12 @@
#include <stratosphere/fs/fs_content_attributes.hpp> #include <stratosphere/fs/fs_content_attributes.hpp>
/* ACCURATE_TO_VERSION: 17.5.0.0 */ /* ACCURATE_TO_VERSION: 17.5.0.0 */
#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ #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, 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, 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, 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, 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, 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, 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_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) 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_0 = ::ams::TargetFirmware_17_0_0,
Version_17_0_1 = ::ams::TargetFirmware_17_0_1, Version_17_0_1 = ::ams::TargetFirmware_17_0_1,
Version_18_0_0 = ::ams::TargetFirmware_18_0_0, 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_18_1_0 = ::ams::TargetFirmware_18_1_0,
Version_19_0_0 = ::ams::TargetFirmware_19_0_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, Version_Current = ::ams::TargetFirmware_Current,

View File

@@ -19,14 +19,14 @@
#include <stratosphere/ldr/ldr_types.hpp> #include <stratosphere/ldr/ldr_types.hpp>
#include <stratosphere/sf.hpp> #include <stratosphere/sf.hpp>
#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ #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, 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, const ldr::ProgramAttributes &attrs), (out_program_info, loc, attrs)) \ 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, 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, 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, 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, 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, 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_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) 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 { namespace ams::ldr::pm {
/* Process Manager API. */ /* Process Manager API. */
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit, ldr::ProgramAttributes attrs); Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit);
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc);
Result UnpinProgram(PinId pin_id); Result UnpinProgram(PinId pin_id);
Result SetEnabledProgramVerification(bool enabled); Result SetEnabledProgramVerification(bool enabled);
Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id);
/* Atmosphere extension API. */ /* 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); 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/ncm/ncm_program_location.hpp>
#include <stratosphere/sf/sf_buffer_tags.hpp> #include <stratosphere/sf/sf_buffer_tags.hpp>
#include <stratosphere/ncm/ncm_content_meta_platform.hpp> #include <stratosphere/ncm/ncm_content_meta_platform.hpp>
#include <stratosphere/fs/fs_content_attributes.hpp>
namespace ams::ldr { namespace ams::ldr {
@@ -266,10 +265,4 @@ namespace ams::ldr {
}; };
static_assert(sizeof(Npdm) == 0x80 && util::is_pod<Npdm>::value, "Npdm definition!"); 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); AMS_ASSERT(m_interface != nullptr);
R_RETURN(m_interface->GetPlatform(out, key)); 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, 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, 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, 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, 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_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC) 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 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 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 GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key);
Result HasAttributes(sf::Out<u8> out, u8 attr_mask);
}; };
static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>); static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>);

View File

@@ -121,15 +121,13 @@ namespace ams::ncm {
static const AtmosphereProgramId Mitm; static const AtmosphereProgramId Mitm;
static const AtmosphereProgramId AtmosphereLogManager; static const AtmosphereProgramId AtmosphereLogManager;
static const AtmosphereProgramId AtmosphereMemlet;
}; };
inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul };
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul };
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereMemlet = { 0x0100000000000421ul };
inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) { 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 &) { 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); 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. */ /* Launch user programs off of the SD. */
LaunchFlaggedProgramsOnSdCard(); LaunchFlaggedProgramsOnSdCard();
} }

View File

@@ -50,7 +50,7 @@ namespace ams::erpt::srv {
R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument());
R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), 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(); ManagerImpl::NotifyAll();
@@ -142,11 +142,6 @@ namespace ams::erpt::srv {
R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size)); 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) { 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 ContextEntry *ctx = reinterpret_cast<const ContextEntry *>( ctx_buffer.GetPointer());
const u8 *data = reinterpret_cast<const u8 *>(data_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(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument());
R_UNLESS(num_attachments <= AttachmentsPerReportMax, 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(); ManagerImpl::NotifyAll();
@@ -174,29 +169,6 @@ namespace ams::erpt::srv {
R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess()));
} }
Result ContextImpl::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) { Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) {
R_RETURN(Reporter::RegisterRunningApplet(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 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 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 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 RegisterRunningApplet(ncm::ProgramId program_id);
Result UnregisterRunningApplet(ncm::ProgramId program_id); Result UnregisterRunningApplet(ncm::ProgramId program_id);
Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration); 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))); R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str)));
/* Create report. */ /* 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(); R_SUCCEED();
} }

View File

@@ -51,8 +51,8 @@ namespace ams::erpt::srv {
R_RETURN(JournalForReports::DeleteReport(report_id)); R_RETURN(JournalForReports::DeleteReport(report_id));
} }
Result Journal::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) {
R_RETURN(JournalForAttachments::GetAttachmentList(out_count, out_infos, max_out_infos, report_id)); R_RETURN(JournalForAttachments::GetAttachmentList(out, report_id));
} }
util::Uuid Journal::GetJournalId() { util::Uuid Journal::GetJournalId() {

View File

@@ -82,7 +82,7 @@ namespace ams::erpt::srv {
static void CleanupAttachments(); static void CleanupAttachments();
static Result CommitJournal(Stream *stream); static Result CommitJournal(Stream *stream);
static Result DeleteAttachments(ReportId report_id); 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 u32 GetUsedStorage();
static Result RestoreJournal(Stream *stream); static Result RestoreJournal(Stream *stream);
@@ -99,7 +99,7 @@ namespace ams::erpt::srv {
static void CleanupReports(); static void CleanupReports();
static Result Commit(); static Result Commit();
static Result Delete(ReportId report_id); 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 util::Uuid GetJournalId();
static s64 GetMaxReportSize(); static s64 GetMaxReportSize();
static Result GetReportList(ReportList *out, ReportType type_filter); static Result GetReportList(ReportList *out, ReportType type_filter);

View File

@@ -77,19 +77,14 @@ namespace ams::erpt::srv {
R_SUCCEED(); R_SUCCEED();
} }
Result JournalForAttachments::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) {
if (hos::GetVersion() >= hos::Version_20_0_0) {
/* TODO: What define gives a minimum of 10? */
R_UNLESS(max_out_infos >= 10, erpt::ResultInvalidArgument());
}
u32 count = 0; 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) { 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(); R_SUCCEED();
} }

View File

@@ -86,23 +86,10 @@ namespace ams::erpt::srv {
R_SUCCEED(); 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()); R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument());
auto *attachment_list = reinterpret_cast<AttachmentList *>(out_list.GetPointer()); R_RETURN(Journal::GetAttachmentList(reinterpret_cast<AttachmentList *>(out_list.GetPointer()), report_id));
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();
} }
} }

View File

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

View File

@@ -414,7 +414,7 @@ namespace ams::erpt::srv {
R_SUCCEED(); 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. */ /* Create a context record for the report. */
auto record = std::make_unique<ContextRecord>(); auto record = std::make_unique<ContextRecord>();
R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory());
@@ -423,10 +423,10 @@ namespace ams::erpt::srv {
R_TRY(record->Initialize(ctx, data, data_size)); R_TRY(record->Initialize(ctx, data, data_size));
/* Create the report. */ /* 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. */ /* Clear the automatic categories, when we're done with our report. */
ON_SCOPE_EXIT { ON_SCOPE_EXIT {
Context::ClearContext(CategoryId_ErrorInfo); Context::ClearContext(CategoryId_ErrorInfo);
@@ -444,7 +444,7 @@ namespace ams::erpt::srv {
R_TRY(SubmitReportDefaults(ctx)); R_TRY(SubmitReportDefaults(ctx));
/* Generate report id. */ /* 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. */ /* Get posix timestamps. */
time::PosixTime timestamp_user; time::PosixTime timestamp_user;

View File

@@ -58,8 +58,8 @@ namespace ams::erpt::srv {
private: 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); 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: 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, 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, 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);
}; };
} }

View File

@@ -69,7 +69,7 @@ namespace ams::fs {
return GetReference(g_stratosphere_romfs_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. */ /* Print a path suitable for the remote service. */
fssrv::sf::Path sf_path; fssrv::sf::Path sf_path;
R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path)); R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path));
@@ -79,11 +79,7 @@ namespace ams::fs {
R_TRY(fsp->SetCurrentProcess({})); R_TRY(fsp->SetCurrentProcess({}));
sf::SharedPointer<fssrv::sf::IFileSystem> fs; 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)), sf_path, attr, program_id));
R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), attr, program_id, storage_id));
} else {
R_TRY(fsp->OpenCodeFileSystemDeprecated4(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id));
}
/* Allocate a new filesystem wrapper. */ /* Allocate a new filesystem wrapper. */
auto fsa = std::make_unique<impl::FileSystemServiceObjectAdapter>(std::move(fs)); auto fsa = std::make_unique<impl::FileSystemServiceObjectAdapter>(std::move(fs));
@@ -152,7 +148,7 @@ namespace ams::fs {
R_SUCCEED(); 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. */ /* If we can open an sd card code fs, use it. */
R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id))); 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))); R_SUCCEED_IF(R_SUCCEEDED(OpenStratosphereCodeFileSystemImpl(out, program_id)));
/* Otherwise, fall back to a normal code fs. */ /* 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) { Result OpenHblCodeFileSystemImpl(std::unique_ptr<fsa::IFileSystem> *out) {
@@ -338,12 +334,11 @@ namespace ams::fs {
util::optional<SdCardRedirectionCodeFileSystem> m_code_fs; util::optional<SdCardRedirectionCodeFileSystem> m_code_fs;
util::optional<ReadOnlyFileSystem> m_hbl_fs; util::optional<ReadOnlyFileSystem> m_hbl_fs;
ncm::ProgramId m_program_id; ncm::ProgramId m_program_id;
ncm::StorageId m_storage_id;
bool m_initialized; bool m_initialized;
public: public:
AtmosphereCodeFileSystem() : m_initialized(false) { /* ... */ } 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); AMS_ABORT_UNLESS(!m_initialized);
/* If we're hbl, we need to open a hbl fs. */ /* If we're hbl, we need to open a hbl fs. */
@@ -355,11 +350,10 @@ namespace ams::fs {
/* Open the code filesystem. */ /* Open the code filesystem. */
std::unique_ptr<fsa::IFileSystem> fsa; 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_code_fs.emplace(std::move(fsa), program_id, is_specific);
m_program_id = program_id; m_program_id = program_id;
m_storage_id = storage_id;
m_initialized = true; m_initialized = true;
R_SUCCEED(); 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 { auto mount_impl = [=]() -> Result {
/* Clear the output. */ /* Clear the output. */
std::memset(out, 0, sizeof(*out)); std::memset(out, 0, sizeof(*out));
@@ -405,7 +399,7 @@ namespace ams::fs {
/* Open the code file system. */ /* Open the code file system. */
std::unique_ptr<fsa::IFileSystem> fsa; 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. */ /* Register. */
R_RETURN(fsa::Register(name, std::move(fsa))); R_RETURN(fsa::Register(name, std::move(fsa)));
@@ -420,7 +414,7 @@ namespace ams::fs {
R_SUCCEED(); 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 { auto mount_impl = [=]() -> Result {
/* Clear the output. */ /* Clear the output. */
std::memset(out, 0, sizeof(*out)); std::memset(out, 0, sizeof(*out));
@@ -436,7 +430,7 @@ namespace ams::fs {
R_UNLESS(ams_code_fs != nullptr, fs::ResultAllocationMemoryFailedInCodeA()); R_UNLESS(ams_code_fs != nullptr, fs::ResultAllocationMemoryFailedInCodeA());
/* Initialize the code file system. */ /* 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. */ /* Register. */
R_RETURN(fsa::Register(name, std::move(ams_code_fs))); R_RETURN(fsa::Register(name, std::move(ams_code_fs)));
@@ -451,7 +445,7 @@ namespace ams::fs {
R_SUCCEED(); 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 { auto mount_impl = [=]() -> Result {
/* Clear the output. */ /* Clear the output. */
std::memset(out, 0, sizeof(*out)); std::memset(out, 0, sizeof(*out));
@@ -464,7 +458,7 @@ namespace ams::fs {
/* Open the code file system. */ /* Open the code file system. */
std::unique_ptr<fsa::IFileSystem> fsa; 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. */ /* Create a wrapper fs. */
auto wrap_fsa = std::make_unique<SdCardRedirectionCodeFileSystem>(std::move(fsa), program_id, false); 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) { Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
::FsCodeInfo dummy; ::FsCodeInfo dummy;
::FsFileSystem fs; ::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)); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED(); 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) { 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; ::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)); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED(); 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) { 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; ::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)); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED(); 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; ::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 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)));
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs)); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
R_SUCCEED(); R_SUCCEED();

View File

@@ -21,7 +21,7 @@ namespace ams::fs::impl {
#define ADD_ENUM_CASE(v) case v: return #v #define ADD_ENUM_CASE(v) case v: return #v
template<> const char *IdString::ToString<pkg1::KeyGeneration>(pkg1::KeyGeneration id) { 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) { switch (id) {
using enum pkg1::KeyGeneration; using enum pkg1::KeyGeneration;
case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; 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_16_0_0: return "16.0.0-16.0.3";
case KeyGeneration_17_0_0: return "17.0.0-17.0.1"; 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_18_0_0: return "18.0.0-18.1.0";
case KeyGeneration_19_0_0: return "19.0.0-19.0.1"; case KeyGeneration_19_0_0: return "19.0.0-";
case KeyGeneration_20_0_0: return "20.0.0-";
default: return "Unknown"; default: return "Unknown";
} }
} }

View File

@@ -482,16 +482,11 @@ namespace ams::fssrv {
AMS_UNUSED(out_fs, out_verif, path, attr, program_id); 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_ABORT("TODO");
AMS_UNUSED(out_fs, out_verif, path, attr, program_id); 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) { Result FileSystemProxyImpl::IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
AMS_ABORT("TODO"); AMS_ABORT("TODO");
AMS_UNUSED(out, process_id); AMS_UNUSED(out, process_id);

View File

@@ -32,14 +32,8 @@ Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) {
return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id); return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id);
} }
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr) { Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) {
const struct { return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status,
LoaderProgramAttributes attr;
u16 pad1;
u32 pad2;
NcmProgramLocation loc;
} in = { *attr, 0, 0, *loc };
return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, in, *out_status,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize }, .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } }, .buffers = { { out_program_info, sizeof(*out_program_info) } },
); );

View File

@@ -19,7 +19,7 @@ typedef struct {
Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id);
Result ldrDmntAtmosphereHasLaunchedBootProgram(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); Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -19,14 +19,13 @@
namespace ams::ldr::pm { namespace ams::ldr::pm {
/* Information API. */ /* Information API. */
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit, ldr::ProgramAttributes attrs) { Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) {
static_assert(sizeof(attrs) == sizeof(::LoaderProgramAttributes)); R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, out));
R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs)), 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)); 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) { 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))); 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_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!");
static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); 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) { Result SetEnabledProgramVerification(bool enabled) {

View File

@@ -534,34 +534,4 @@ namespace ams::ncm {
R_SUCCEED(); 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 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 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 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 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 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 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>); 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)); static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8));
R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast<u8 *>(out.GetPointer()), Convert(key))); 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>); static_assert(ncm::IsIContentMetaDatabase<RemoteContentMetaDatabaseImpl>);
#endif #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_TRY_CATCH(svc::CreateSharedMemory(std::addressof(handle), size, svc_my_perm, svc_other_perm)) {
R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles()) R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles())
R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfResource()) R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfResource())
R_CONVERT(svc::ResultLimitReached, os::ResultOutOfMemory())
} R_END_TRY_CATCH_WITH_ABORT_UNLESS; } R_END_TRY_CATCH_WITH_ABORT_UNLESS;
*out = handle; *out = handle;

View File

@@ -16,11 +16,11 @@
#pragma once #pragma once
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #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_MICRO 0
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 19
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 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_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0)
#define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) #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_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_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_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_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
@@ -162,12 +158,8 @@ namespace ams {
TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0,
TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1,
TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, 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_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0,
TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_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, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,

View File

@@ -21,20 +21,20 @@ R_DEFINE_NAMESPACE_RESULT_MODULE(ams::ldr, 9);
namespace ams::ldr { namespace ams::ldr {
R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1); R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1);
R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2); R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2);
R_DEFINE_ERROR_RESULT(MetaOverflow, 3); R_DEFINE_ERROR_RESULT(MetaOverflow, 3);
R_DEFINE_ERROR_RESULT(InvalidMeta, 4); R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
R_DEFINE_ERROR_RESULT(InvalidNso, 5); R_DEFINE_ERROR_RESULT(InvalidNso, 5);
R_DEFINE_ERROR_RESULT(InvalidPath, 6); R_DEFINE_ERROR_RESULT(InvalidPath, 6);
R_DEFINE_ERROR_RESULT(MaxProcess, 7); R_DEFINE_ERROR_RESULT(MaxProcess, 7);
R_DEFINE_ERROR_RESULT(NotPinned, 8); R_DEFINE_ERROR_RESULT(NotPinned, 8);
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
R_DEFINE_ERROR_RESULT(InvalidVersion, 10); R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11);
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); 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(OutOfAddressSpace, 51);
R_DEFINE_ERROR_RESULT(InvalidNroImage, 52); R_DEFINE_ERROR_RESULT(InvalidNroImage, 52);

View File

@@ -112,14 +112,6 @@ _ZN3ams4kern4init10StartCore0Emm:
#endif #endif
2: /* We're EL1. */ 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. */ /* Disable the MMU/Caches. */
bl _ZN3ams4kern4init19DisableMmuAndCachesEv bl _ZN3ams4kern4init19DisableMmuAndCachesEv
@@ -154,15 +146,11 @@ _ZN3ams4kern4init10StartCore0Emm:
/* Save the offset to virtual address from this page's physical address for our use. */ /* Save the offset to virtual address from this page's physical address for our use. */
mov x24, x1 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. */ /* 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. */ /* 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 **) */ /* Call ams::kern::init::InitializeCore(uintptr_t, void **) */
mov x1, x0 /* Kernelldr returns a state object for the kernel to re-use. */ mov x1, x0 /* Kernelldr returns a state object for the kernel to re-use. */
mov x0, x21 /* Use the address we determined earlier. */ mov x0, x21 /* Use the address we determined earlier. */
nop
INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase1EmPPv) INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase1EmPPv)
/* Get the init arguments for core 0. */ /* Get the init arguments for core 0. */
@@ -176,7 +164,6 @@ _ZN3ams4kern4init10StartCore0Emm:
/* Perform further initialization with the stack pointer set up, as required. */ /* Perform further initialization with the stack pointer set up, as required. */
/* This will include e.g. unmapping the identity mapping. */ /* This will include e.g. unmapping the identity mapping. */
nop
INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase2Ev) INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase2Ev)
/* Get the init arguments for core 0. */ /* Get the init arguments for core 0. */
@@ -233,14 +220,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
#endif #endif
2: /* We're EL1. */ 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. */ /* Disable the MMU/Caches. */
bl _ZN3ams4kern4init19DisableMmuAndCachesEv bl _ZN3ams4kern4init19DisableMmuAndCachesEv
@@ -262,7 +241,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
b.eq 3f b.eq 3f
b 4f b 4f
3: /* We're running on a Cortex-A53/Cortex-A57. */ 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)] ldr x1, [x20, #(INIT_ARGUMENTS_CPUACTLR)]
msr cpuactlr_el1, x1 msr cpuactlr_el1, x1
ldr x1, [x20, #(INIT_ARGUMENTS_CPUECTLR)] ldr x1, [x20, #(INIT_ARGUMENTS_CPUECTLR)]
@@ -287,9 +265,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
/* Set the stack pointer. */ /* Set the stack pointer. */
mov sp, x2 mov sp, x2
/* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */
mov x18, #0
/* Invoke the entrypoint. */ /* Invoke the entrypoint. */
blr x1 blr x1
@@ -413,6 +388,14 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv:
/* The stack isn't set up, so we'll need to trash a register. */ /* The stack isn't set up, so we'll need to trash a register. */
mov x22, x30 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. */ /* Set SCTLR_EL1 to disable the caches and mmu. */
/* SCTLR_EL1: */ /* SCTLR_EL1: */
/* - M = 0 */ /* - M = 0 */
@@ -430,44 +413,27 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv:
mov x30, x22 mov x30, x22
ret ret
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */ /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */
.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits .section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits
.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv .global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function .type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function
_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv: _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv:
/* The stack isn't set up, so we'll need to trash a register. */ /* The stack isn't set up, so we'll need to trash a register. */
mov x24, x30 mov x23, x30
/* CacheLineIdAccessor clidr_el1; */ /* Ensure that the cache is coherent. */
mrs x10, clidr_el1 bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
/* 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
/* int level = levels_of_unification */ bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
/* while (level <= levels_of_coherency) { */ bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
cmp w9, w10
b.hi 1f
0: /* Invalidate the entire TLB, and ensure instruction consistency. */
/* FlushEntireDataCacheImplWithoutStack(level); */ tlbi vmalle1is
mov w0, w9
bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv
/* level++; */
cmp w9, w10
add w9, w9, #1
/* } */
b.cc 0b
/* cpu::DataSynchronizationBarrier(); */
dsb sy dsb sy
isb
1: mov x30, x23
mov x30, x24
ret ret
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheLocalWithoutStack() */ /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheLocalWithoutStack() */
@@ -509,27 +475,44 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv:
mov x30, x24 mov x30, x24
ret ret
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */ /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */
.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits .section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits
.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv .global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function .type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function
_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv: _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv:
/* The stack isn't set up, so we'll need to trash a register. */ /* 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. */ /* CacheLineIdAccessor clidr_el1; */
bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv 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. */ 0:
tlbi vmalle1is /* FlushEntireDataCacheImplWithoutStack(level); */
mov w0, w9
bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv
/* level++; */
cmp w9, w10
add w9, w9, #1
/* } */
b.cc 0b
/* cpu::DataSynchronizationBarrier(); */
dsb sy dsb sy
isb
mov x30, x23 1:
mov x30, x24
ret ret
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheImplWithoutStack() */ /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheImplWithoutStack() */

View File

@@ -354,12 +354,21 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv:
mrs x17, ttbr0_el1 mrs x17, ttbr0_el1
and x17, x17, #(0xFFFF << 48) 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 mrs x16, far_el1
lsr x16, x16, #12 lsr x16, x16, #12
orr x17, x16, x17 orr x17, x16, x17
tlbi vae1, 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. */ /* Ensure instruction consistency. */
dsb ish dsb ish
isb isb
@@ -476,16 +485,33 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv:
b 3b b 3b
4: /* Check if there's a TLB conflict that caused the abort. */ 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 mrs x0, esr_el1
and x0, x0, #0x3F and x0, x0, #0x3F
cmp x0, #0x30 cmp x0, #0x30
b.ne 1b 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 mrs x0, far_el1
lsr x0, x0, #12 lsr x0, x0, #12
tlbi vaae1, x0 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. */ /* Ensure instruction consistency. */
dsb ish dsb ish
isb isb

View File

@@ -24,7 +24,7 @@ namespace ams {
namespace { namespace {
/* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */ /* 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]; alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
} }

View File

@@ -17,7 +17,6 @@
#include "../amsmitm_fs_utils.hpp" #include "../amsmitm_fs_utils.hpp"
#include "fsmitm_romfs.hpp" #include "fsmitm_romfs.hpp"
#include "fsmitm_layered_romfs_storage.hpp" #include "fsmitm_layered_romfs_storage.hpp"
#include "memlet/memlet.h"
namespace ams::mitm::fs { namespace ams::mitm::fs {
@@ -27,8 +26,6 @@ namespace ams::mitm::fs {
namespace { namespace {
constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB;
struct ApplicationWithDynamicHeapInfo { struct ApplicationWithDynamicHeapInfo {
ncm::ProgramId program_id; ncm::ProgramId program_id;
size_t dynamic_app_heap_size; size_t dynamic_app_heap_size;
@@ -44,7 +41,7 @@ namespace ams::mitm::fs {
/* Fire Emblem: Engage. */ /* Fire Emblem: Engage. */
/* Requirement ~32+ MB. */ /* Requirement ~32+ MB. */
/* No particular heap sensitivity. */ /* No particular heap sensitivity. */
{ 0x0100A6301214E000, 20_MB, 0_MB }, { 0x0100A6301214E000, 16_MB, 0_MB },
/* The Legend of Zelda: Tears of the Kingdom. */ /* The Legend of Zelda: Tears of the Kingdom. */
/* Requirement ~48 MB. */ /* 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. */ /* 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)); 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. */ /* 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)); 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. */ /* Dynamic allocation globals. */
constinit os::SdkMutex g_romfs_build_lock; constinit os::SdkMutex g_romfs_build_lock;
constinit ncm::ProgramId g_dynamic_heap_program_id{}; 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<os::AllocateUnsafeMemory, os::FreeUnsafeMemory> g_dynamic_app_heap;
constinit DynamicHeap<MapByHeap, UnmapByHeap> g_dynamic_sys_heap; constinit DynamicHeap<MapByHeap, UnmapByHeap> g_dynamic_sys_heap;
constinit DynamicHeap<MapAppletMemory, UnmapAppletMemory> g_dynamic_let_heap;
void InitializeDynamicHeapForBuildRomfs(ncm::ProgramId program_id) { void InitializeDynamicHeapForBuildRomfs(ncm::ProgramId program_id) {
if (program_id == g_dynamic_heap_program_id && g_dynamic_app_heap.heap_size > 0) { 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) { if (g_dynamic_sys_heap.heap_size > 0) {
g_dynamic_sys_heap.Map(); 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_building_from_dynamic_heap = false;
g_dynamic_app_heap.TryRelease(); 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) { void *AllocateTracked(AllocationType type, size_t size) {
if (g_building_from_dynamic_heap) { AMS_UNUSED(type);
void *ret = nullptr;
if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) {
ret = g_dynamic_let_heap.Allocate(size);
}
if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) { if (g_building_from_dynamic_heap) {
ret = g_dynamic_app_heap.Allocate(size); void *ret = g_dynamic_app_heap.Allocate(size);
}
if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) { if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) {
ret = g_dynamic_sys_heap.Allocate(size); ret = g_dynamic_sys_heap.Allocate(size);
@@ -285,11 +211,7 @@ namespace ams::mitm::fs {
AMS_UNUSED(type); AMS_UNUSED(type);
AMS_UNUSED(size); AMS_UNUSED(size);
if (g_dynamic_let_heap.TryFree(p)) { if (g_dynamic_app_heap.TryFree(p)) {
if (!g_building_from_dynamic_heap) {
g_dynamic_let_heap.TryRelease();
}
} else if (g_dynamic_app_heap.TryFree(p)) {
if (!g_building_from_dynamic_heap) { if (!g_building_from_dynamic_heap) {
g_dynamic_app_heap.TryRelease(); g_dynamic_app_heap.TryRelease();
} }
@@ -1099,7 +1021,6 @@ namespace ams::mitm::fs {
g_dynamic_heap_program_id = program_id; g_dynamic_heap_program_id = program_id;
g_dynamic_app_heap.heap_size = GetDynamicAppHeapSize(g_dynamic_heap_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_sys_heap.heap_size = GetDynamicSysHeapSize(g_dynamic_heap_program_id);
g_dynamic_let_heap.heap_size = MaximumRomfsBuildAppletMemorySize;
/* Set output. */ /* Set output. */
*out_size = g_dynamic_app_heap.heap_size; *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 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) { 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, attrs); 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) { 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, attrs); m_result = this->Initialize(loc, platform);
} }
ScopedCodeMount::~ScopedCodeMount() { 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. */ /* Capture override status, if necessary. */
this->EnsureOverrideStatus(loc); this->EnsureOverrideStatus(loc);
AMS_ABORT_UNLESS(m_has_status); AMS_ABORT_UNLESS(m_has_status);
/* Get the content path. */ /* Get the content path. */
char content_path[fs::EntryNameLengthMax + 1]; 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. */ /* Get the content attributes. */
const auto content_attributes = attrs.content_attributes; const auto content_attributes = GetPlatformContentAttributes(platform);
/* Mount the atmosphere code file system. */ /* 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; m_mounted_ams = true;
/* Mount the sd or base code file system. */ /* 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; m_mounted_sd_or_code = true;
/* Mount the base code file system. */ /* 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; m_mounted_code = true;
} }
@@ -83,7 +83,7 @@ namespace ams::ldr {
} }
/* Redirection API. */ /* 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. */ /* Check for storage id none. */
if (static_cast<ncm::StorageId>(loc.storage_id) == ncm::StorageId::None) { if (static_cast<ncm::StorageId>(loc.storage_id) == ncm::StorageId::None) {
std::memset(out_path, 0, out_size); std::memset(out_path, 0, out_size);
@@ -92,7 +92,7 @@ namespace ams::ldr {
} }
/* Get the content attributes. */ /* Get the content attributes. */
const auto content_attributes = attrs.content_attributes; const auto content_attributes = GetPlatformContentAttributes(platform);
AMS_UNUSED(content_attributes); AMS_UNUSED(content_attributes);
lr::Path path; lr::Path path;
@@ -166,4 +166,12 @@ namespace ams::ldr {
R_SUCCEED(); 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_sd_or_code;
bool m_mounted_code; bool m_mounted_code;
public: public:
ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform);
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs); ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, ncm::ContentMetaPlatform platform);
~ScopedCodeMount(); ~ScopedCodeMount();
Result GetResult() const { Result GetResult() const {
@@ -59,7 +59,7 @@ namespace ams::ldr {
return m_base_code_verification_data; return m_base_code_verification_data;
} }
private: 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); void EnsureOverrideStatus(const ncm::ProgramLocation &loc);
}; };
@@ -76,8 +76,10 @@ namespace ams::ldr {
#define ENCODE_CMPT_PATH(relative) "cmpt:" relative #define ENCODE_CMPT_PATH(relative) "cmpt:" relative
/* Redirection API. */ /* 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 RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc);
Result RedirectHtmlDocumentPathForHbl(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 }, { 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[] = { constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = {
{ ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 },
{ ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_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("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("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("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; constinit ArgumentStore g_argument_store;
bool IsValidProgramAttributes(const ldr::ProgramAttributes &attrs) { bool IsValidPlatform(ncm::ContentMetaPlatform platform) {
/* Check that the attributes are valid; on NX, this means Platform = NX + no content attrs. */ return platform == ncm::ContentMetaPlatform::Nx;
if (attrs.platform != ncm::ContentMetaPlatform::Nx) { }
return false;
} Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) {
if (attrs.content_attributes != fs::ContentAttributes_None) { /* Check that the platform is valid. */
return false; 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) { Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) {
/* Check that the program attributes are valid. */ R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, ncm::ContentMetaPlatform::Nx));
R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes());
/* Get the location and override status. */
ncm::ProgramLocation loc;
cfg::OverrideStatus override_status;
R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id));
/* Get the program path. */
char path[fs::EntryNameLengthMax];
R_TRY(GetProgramPath(path, sizeof(path), loc, attrs));
path[sizeof(path) - 1] = '\x00';
/* Create the process. */
R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, attrs));
} }
Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
/* Check that the program attributes are valid. */ R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, ncm::ContentMetaPlatform::Nx));
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::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {

View File

@@ -21,16 +21,16 @@ namespace ams::ldr {
class LoaderService { class LoaderService {
public: public:
/* Official commands. */ /* 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. */ /* Create a handle to set the output to when done. */
os::NativeHandle handle = os::InvalidNativeHandle; os::NativeHandle handle = os::InvalidNativeHandle;
ON_SCOPE_EXIT { proc_h.SetValue(handle, true); }; 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) { Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc) {
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc, attrs)); R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc));
} }
Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &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); 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) { 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, attrs)); 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) { 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)); R_RETURN(this->PinProgram(out_id.GetPointer(), loc, override_status));
} }
private: private:
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, 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, const ProgramAttributes &attrs); 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 PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
Result SetProgramArgument(ncm::ProgramId program_id, const void *argument, size_t size); 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); 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. */ /* 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. */ /* Mount code. */
AMS_UNUSED(path); AMS_UNUSED(path);
ScopedCodeMount mount(loc, override_status, attrs); ScopedCodeMount mount(loc, override_status, platform);
R_TRY(mount.GetResult()); R_TRY(mount.GetResult());
/* Load meta, possibly from cache. */ /* Load meta, possibly from cache. */
Meta meta; 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. */ /* Validate meta. */
R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData())); R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData()));
@@ -720,16 +720,16 @@ namespace ams::ldr {
R_SUCCEED(); 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; Meta meta;
/* Load Meta. */ /* Load Meta. */
{ {
AMS_UNUSED(path); AMS_UNUSED(path);
ScopedCodeMount mount(loc, attrs); ScopedCodeMount mount(loc, platform);
R_TRY(mount.GetResult()); 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) { if (out_status != nullptr) {
*out_status = mount.GetOverrideStatus(); *out_status = mount.GetOverrideStatus();
} }

View File

@@ -19,8 +19,8 @@
namespace ams::ldr { namespace ams::ldr {
/* Process Creation API. */ /* 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);
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);
Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
Result UnpinProgram(PinId id); 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