Compare commits
4 Commits
20_support
...
gcc15_supp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4859bcc0fe | ||
|
|
0ecd822c26 | ||
|
|
b1e0dad506 | ||
|
|
c55606cfdb |
@@ -13,6 +13,7 @@ Components
|
||||
Atmosphère consists of multiple components, each of which replaces/modifies a different component of the system:
|
||||
|
||||
* Fusée: First-stage Loader, responsible for loading and validating stage 2 (custom TrustZone) plus package2 (Kernel/FIRM sysmodules), and patching them as needed. This replaces all functionality normally in Package1loader/NX Bootloader.
|
||||
* Sept: Payload used to enable support for runtime key derivation on 7.0.0.
|
||||
* Exosphère: Customized TrustZone, to run a customized Secure Monitor
|
||||
* Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images
|
||||
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions
|
||||
|
||||
@@ -50,7 +50,6 @@ dist: dist-no-debug
|
||||
cp $(CURRENT_DIRECTORY)/stratosphere/sm/$(ATMOSPHERE_OUT_DIR)/sm.elf $(DIST_DIR)/sm.elf
|
||||
cp $(CURRENT_DIRECTORY)/stratosphere/spl/$(ATMOSPHERE_OUT_DIR)/spl.elf $(DIST_DIR)/spl.elf
|
||||
cp $(CURRENT_DIRECTORY)/stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.elf $(DIST_DIR)/TioServer.elf
|
||||
cp $(CURRENT_DIRECTORY)/stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.elf $(DIST_DIR)/memlet.elf
|
||||
cp $(CURRENT_DIRECTORY)/troposphere/daybreak/daybreak.elf $(DIST_DIR)/daybreak.elf
|
||||
cp $(CURRENT_DIRECTORY)/troposphere/haze/haze.elf $(DIST_DIR)/haze.elf
|
||||
cp $(CURRENT_DIRECTORY)/troposphere/reboot_to_payload/reboot_to_payload.elf $(DIST_DIR)/reboot_to_payload.elf
|
||||
@@ -88,7 +87,6 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
||||
#mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609
|
||||
mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623
|
||||
@@ -106,7 +104,6 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
||||
cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp
|
||||
cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp
|
||||
cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp
|
||||
cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp
|
||||
@build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs
|
||||
rm -r $(DIST_DIR)/stratosphere_romfs
|
||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro
|
||||
|
||||
@@ -1,29 +1,4 @@
|
||||
# Changelog
|
||||
## 1.9.0
|
||||
+ Basic support was added for 20.0.0.
|
||||
+ The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes.
|
||||
+ There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update.
|
||||
+ The same action item from 18.0.0 remains, and I believe in my heart of hearts that it will be addressed eventually. Someone has told me they're working on it.
|
||||
+ There aren't (to my knowledge) outstanding 19.0.0 items any more.
|
||||
+ **Please note**: As a result of changes made to nintendo's software in 20.0.0, there is roughly 10MB less memory available for custom system modules.
|
||||
+ We can only steal a maximum of 14MB from the applet pool, down from 40MB.
|
||||
+ To compensate for this, `ams.mitm`'s heap usage has been reduced by 20MB.
|
||||
+ To facilitate this, a new helper module (`memlet`) was added, so that memory may be temporarily stolen during the romfs building process.
|
||||
+ Hopefully, this results in relatively little breakage, however it is possible that user mods which replace extremely large numbers of files in The Legend of Zelda: Tears of the Kingdom may no longer function.
|
||||
+ If you are affected by this, you will see "Data abort (0x101)" when trying to launch the game with mods.
|
||||
+ Please reach out to `sciresm` on discord if this occurs to share your error report binary. However, some issues may be impossible to fix.
|
||||
+ I apologize sincerely if the issue is impossible to resolve, but I have been forced unavoidably to make compromises here, and I think this is the best balance to be struck.
|
||||
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ `loader` was updated to reflect the latest official behavior.
|
||||
+ `pm` was updated to reflect the latest official behavior.
|
||||
+ `ncm` was partially updated to reflect the latest official behavior.
|
||||
+ `erpt` was updated to reflect the latest official behavior.
|
||||
+ Atmosphère was updated to use GCC 15/newlib (latest devkitA64/devkitARM releases).
|
||||
+ A number of improvements were made to the dmnt cheat engine.
|
||||
+ New instructions were added, and instructions were updated for improved/new functionality.
|
||||
+ Please see the documents for details -- thanks @tomvita!
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.8.0
|
||||
+ Basic support was added for 19.0.0.
|
||||
+ The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes.
|
||||
|
||||
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 20.0.0**
|
||||
**1.0.0 - 19.0.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
||||
8
emummc/source/FS/FS_offsets.c
vendored
8
emummc/source/FS/FS_offsets.c
vendored
@@ -75,8 +75,6 @@
|
||||
#include "offsets/1810_exfat.h"
|
||||
#include "offsets/1900.h"
|
||||
#include "offsets/1900_exfat.h"
|
||||
#include "offsets/2000.h"
|
||||
#include "offsets/2000_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@@ -163,8 +161,6 @@ DEFINE_OFFSET_STRUCT(_1810);
|
||||
DEFINE_OFFSET_STRUCT(_1810_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1900);
|
||||
DEFINE_OFFSET_STRUCT(_1900_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_2000);
|
||||
DEFINE_OFFSET_STRUCT(_2000_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@@ -286,10 +282,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1900));
|
||||
case FS_VER_19_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1900_EXFAT));
|
||||
case FS_VER_20_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_2000));
|
||||
case FS_VER_20_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
||||
3
emummc/source/FS/FS_versions.h
vendored
3
emummc/source/FS/FS_versions.h
vendored
@@ -110,9 +110,6 @@ enum FS_VER
|
||||
FS_VER_19_0_0,
|
||||
FS_VER_19_0_0_EXFAT,
|
||||
|
||||
FS_VER_20_0_0,
|
||||
FS_VER_20_0_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
||||
59
emummc/source/FS/offsets/2000.h
vendored
59
emummc/source/FS/offsets/2000.h
vendored
@@ -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__
|
||||
59
emummc/source/FS/offsets/2000_exfat.h
vendored
59
emummc/source/FS/offsets/2000_exfat.h
vendored
@@ -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__
|
||||
@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
||||
/* TODO: Update on next change of keys. */
|
||||
/* Mariko Development Master Kek Source. */
|
||||
.byte 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
|
||||
.byte 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70
|
||||
|
||||
/* Mariko Production Master Kek Source. */
|
||||
.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
|
||||
.byte 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80
|
||||
|
||||
/* Development Master Key Vectors. */
|
||||
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
|
||||
@@ -110,7 +110,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */
|
||||
.byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */
|
||||
.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */
|
||||
.byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */
|
||||
|
||||
/* Production Master Key Vectors. */
|
||||
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
|
||||
@@ -132,7 +131,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */
|
||||
.byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */
|
||||
.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */
|
||||
.byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */
|
||||
|
||||
/* Device Master Key Source Sources. */
|
||||
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
|
||||
@@ -151,7 +149,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */
|
||||
.byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */
|
||||
.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */
|
||||
.byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */
|
||||
|
||||
/* Development Device Master Kek Sources. */
|
||||
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
|
||||
@@ -170,7 +167,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */
|
||||
.byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */
|
||||
.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */
|
||||
.byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */
|
||||
|
||||
/* Production Device Master Kek Sources. */
|
||||
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
|
||||
@@ -189,4 +185,3 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */
|
||||
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
|
||||
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
|
||||
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
|
||||
@@ -94,7 +94,7 @@ namespace ams::secmon::boot {
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 20);
|
||||
static_assert(pkg1::KeyGeneration_Count == 19);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -23,17 +23,17 @@ namespace ams::nxboot {
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
|
||||
0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
|
||||
0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8
|
||||
0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
|
||||
@@ -73,7 +73,6 @@ namespace ams::nxboot {
|
||||
{ 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */
|
||||
{ 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */
|
||||
{ 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */
|
||||
{ 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
@@ -93,7 +92,6 @@ namespace ams::nxboot {
|
||||
{ 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */
|
||||
{ 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */
|
||||
{ 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */
|
||||
{ 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
@@ -113,7 +111,6 @@ namespace ams::nxboot {
|
||||
{ 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */
|
||||
{ 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */
|
||||
{ 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */
|
||||
{ 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
@@ -136,7 +133,6 @@ namespace ams::nxboot {
|
||||
{ 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */
|
||||
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */
|
||||
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */
|
||||
{ 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
@@ -159,7 +155,6 @@ namespace ams::nxboot {
|
||||
{ 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */
|
||||
{ 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */
|
||||
{ 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */
|
||||
{ 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace ams::nxboot {
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 20);
|
||||
static_assert(pkg1::KeyGeneration_Count == 19);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -263,8 +263,6 @@ namespace ams::nxboot {
|
||||
return ams::TargetFirmware_18_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) {
|
||||
return ams::TargetFirmware_19_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) {
|
||||
return ams::TargetFirmware_20_0_0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -180,9 +180,6 @@ namespace ams::nxboot {
|
||||
FsVersion_19_0_0,
|
||||
FsVersion_19_0_0_Exfat,
|
||||
|
||||
FsVersion_20_0_0,
|
||||
FsVersion_20_0_0_Exfat,
|
||||
|
||||
FsVersion_Count,
|
||||
};
|
||||
|
||||
@@ -275,9 +272,6 @@ namespace ams::nxboot {
|
||||
|
||||
{ 0xD9, 0x4C, 0x68, 0x15, 0xF8, 0xF5, 0x0A, 0x20 }, /* FsVersion_19_0_0 */
|
||||
{ 0xED, 0xA8, 0x78, 0x68, 0xA4, 0x49, 0x07, 0x50 }, /* FsVersion_19_0_0_Exfat */
|
||||
|
||||
{ 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */
|
||||
{ 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */
|
||||
};
|
||||
|
||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||
@@ -667,16 +661,6 @@ namespace ams::nxboot {
|
||||
AddPatch(fs_meta, 0x1A16A5, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
case FsVersion_20_0_0:
|
||||
AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
case FsVersion_20_0_0_Exfat:
|
||||
AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace ams::pkg1 {
|
||||
KeyGeneration_17_0_0 = 0x10,
|
||||
KeyGeneration_18_0_0 = 0x11,
|
||||
KeyGeneration_19_0_0 = 0x12,
|
||||
KeyGeneration_20_0_0 = 0x13,
|
||||
|
||||
KeyGeneration_Count,
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ams::pkg2 {
|
||||
constexpr inline int PayloadCount = 3;
|
||||
|
||||
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */
|
||||
constexpr inline int CurrentBootloaderVersion = 0x17;
|
||||
constexpr inline int CurrentBootloaderVersion = 0x16;
|
||||
|
||||
struct Package2Meta {
|
||||
using Magic = util::FourCC<'P','K','2','1'>;
|
||||
|
||||
@@ -177,7 +177,6 @@ namespace ams::fuse {
|
||||
}
|
||||
|
||||
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
|
||||
TargetFirmware_20_0_0,
|
||||
TargetFirmware_19_0_0,
|
||||
TargetFirmware_17_0_0,
|
||||
TargetFirmware_16_0_0,
|
||||
|
||||
@@ -200,11 +200,6 @@ namespace ams::kern::arch::arm64 {
|
||||
NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
|
||||
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index);
|
||||
Result Finalize();
|
||||
|
||||
static void NoteUpdatedCallback(const void *pt) {
|
||||
/* Note the update. */
|
||||
static_cast<const KPageTable *>(pt)->NoteUpdated();
|
||||
}
|
||||
private:
|
||||
Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll);
|
||||
|
||||
|
||||
@@ -49,8 +49,6 @@ namespace ams::kern::arch::arm64 {
|
||||
EntryLevel level;
|
||||
bool is_contiguous;
|
||||
};
|
||||
|
||||
using EntryUpdatedCallback = void (*)(const void *);
|
||||
private:
|
||||
static constexpr size_t PageBits = util::CountTrailingZeros(PageSize);
|
||||
static constexpr size_t NumLevels = 3;
|
||||
@@ -146,8 +144,8 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const;
|
||||
|
||||
static bool MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt);
|
||||
void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const;
|
||||
static bool MergePages(KVirtualAddress *out, TraversalContext *context);
|
||||
void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const;
|
||||
|
||||
KProcessAddress GetAddressForContext(const TraversalContext *context) const {
|
||||
KProcessAddress addr = m_is_kernel ? static_cast<uintptr_t>(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0;
|
||||
|
||||
@@ -22,139 +22,49 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
class UserspaceAccess {
|
||||
private:
|
||||
class Impl {
|
||||
public:
|
||||
static bool CopyMemoryFromUser(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src);
|
||||
static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src);
|
||||
static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src);
|
||||
static s32 CopyStringFromUser(void *dst, const void *src, size_t size);
|
||||
|
||||
static bool CopyMemoryToUser(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src);
|
||||
static s32 CopyStringToUser(void *dst, const void *src, size_t size);
|
||||
|
||||
static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask);
|
||||
static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value);
|
||||
static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare);
|
||||
|
||||
static bool StoreDataCache(uintptr_t start, uintptr_t end);
|
||||
static bool FlushDataCache(uintptr_t start, uintptr_t end);
|
||||
static bool InvalidateDataCache(uintptr_t start, uintptr_t end);
|
||||
|
||||
static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size);
|
||||
static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size);
|
||||
static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size);
|
||||
};
|
||||
static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src);
|
||||
public:
|
||||
static bool CopyMemoryFromUser(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryFromUser(dst, src, size);
|
||||
}
|
||||
|
||||
static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryFromUserAligned32Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryFromUserAligned64Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src) {
|
||||
return Impl::CopyMemoryFromUserSize64Bit(dst, src);
|
||||
}
|
||||
|
||||
static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src) {
|
||||
return Impl::CopyMemoryFromUserSize32Bit(dst, src);
|
||||
}
|
||||
|
||||
|
||||
static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) {
|
||||
/* Check that the address is within the valid userspace range. */
|
||||
if (const uintptr_t src_uptr = reinterpret_cast<uintptr_t>(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(dst, src);
|
||||
return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src);
|
||||
}
|
||||
|
||||
static s32 CopyStringFromUser(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyStringFromUser(dst, src, size);
|
||||
}
|
||||
static bool CopyMemoryFromUser(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src);
|
||||
static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src);
|
||||
static s32 CopyStringFromUser(void *dst, const void *src, size_t size);
|
||||
|
||||
static bool CopyMemoryToUser(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryToUser(dst, src, size);
|
||||
}
|
||||
static bool CopyMemoryToUser(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size);
|
||||
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src);
|
||||
static s32 CopyStringToUser(void *dst, const void *src, size_t size);
|
||||
|
||||
static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryToUserAligned32Bit(dst, src, size);
|
||||
}
|
||||
static bool ClearMemory(void *dst, size_t size);
|
||||
static bool ClearMemoryAligned32Bit(void *dst, size_t size);
|
||||
static bool ClearMemoryAligned64Bit(void *dst, size_t size);
|
||||
static bool ClearMemorySize32Bit(void *dst);
|
||||
|
||||
static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyMemoryToUserAligned64Bit(dst, src, size);
|
||||
}
|
||||
static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask);
|
||||
static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value);
|
||||
static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare);
|
||||
|
||||
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src) {
|
||||
return Impl::CopyMemoryToUserSize32Bit(dst, src);
|
||||
}
|
||||
static bool StoreDataCache(uintptr_t start, uintptr_t end);
|
||||
static bool FlushDataCache(uintptr_t start, uintptr_t end);
|
||||
static bool InvalidateDataCache(uintptr_t start, uintptr_t end);
|
||||
|
||||
static s32 CopyStringToUser(void *dst, const void *src, size_t size) {
|
||||
return Impl::CopyStringToUser(dst, src, size);
|
||||
}
|
||||
|
||||
static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) {
|
||||
return Impl::UpdateLockAtomic(out, address, if_zero, new_orr_mask);
|
||||
}
|
||||
|
||||
static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) {
|
||||
return Impl::UpdateIfEqualAtomic(out, address, compare_value, new_value);
|
||||
}
|
||||
|
||||
static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) {
|
||||
return Impl::DecrementIfLessThanAtomic(out, address, compare);
|
||||
}
|
||||
|
||||
static bool StoreDataCache(uintptr_t start, uintptr_t end) {
|
||||
return Impl::StoreDataCache(start, end);
|
||||
}
|
||||
|
||||
static bool FlushDataCache(uintptr_t start, uintptr_t end) {
|
||||
return Impl::FlushDataCache(start, end);
|
||||
}
|
||||
|
||||
static bool InvalidateDataCache(uintptr_t start, uintptr_t end) {
|
||||
return Impl::InvalidateDataCache(start, end);
|
||||
}
|
||||
|
||||
static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::ReadIoMemory32Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::ReadIoMemory16Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::ReadIoMemory8Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::WriteIoMemory32Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::WriteIoMemory16Bit(dst, src, size);
|
||||
}
|
||||
|
||||
static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size) {
|
||||
return Impl::WriteIoMemory8Bit(dst, src, size);
|
||||
}
|
||||
static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size);
|
||||
static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size);
|
||||
static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size);
|
||||
static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace ams::kern {
|
||||
size_t m_size;
|
||||
Type m_type;
|
||||
public:
|
||||
static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type, size_t code_size);
|
||||
static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type);
|
||||
static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type);
|
||||
|
||||
static void SetAddressSpaceSize(size_t width, Type type, size_t size);
|
||||
|
||||
@@ -99,7 +99,6 @@ namespace ams::kern {
|
||||
Result Initialize(KProcessAddress st, KProcessAddress nd, KMemoryBlockSlabManager *slab_manager);
|
||||
void Finalize(KMemoryBlockSlabManager *slab_manager);
|
||||
|
||||
static bool GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages);
|
||||
KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const;
|
||||
|
||||
void Update(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr);
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ams::kern {
|
||||
/* Nintendo uses std::mt19937_t for randomness. */
|
||||
/* To save space (and because mt19337_t isn't secure anyway), */
|
||||
/* We will use TinyMT. */
|
||||
static constinit inline bool s_uninitialized_random_generator{true};
|
||||
static constinit inline bool s_initialized_random_generator;
|
||||
static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize};
|
||||
static constinit inline KSpinLock s_random_lock;
|
||||
public:
|
||||
|
||||
@@ -94,11 +94,7 @@ namespace ams::kern {
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const {
|
||||
if (m_resource_limit != nullptr) {
|
||||
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetSize() const { return m_resource_size; }
|
||||
|
||||
@@ -25,35 +25,35 @@ namespace ams::kern {
|
||||
friend class KSystemControl;
|
||||
private:
|
||||
struct KTargetSystemData {
|
||||
bool is_not_debug_mode;
|
||||
bool disable_debug_logging;
|
||||
bool disable_user_exception_handlers;
|
||||
bool disable_debug_memory_fill;
|
||||
bool disable_user_pmu_access;
|
||||
bool disable_kernel_debugging;
|
||||
bool disable_dynamic_resource_limits;
|
||||
bool is_debug_mode;
|
||||
bool enable_debug_logging;
|
||||
bool enable_user_exception_handlers;
|
||||
bool enable_debug_memory_fill;
|
||||
bool enable_user_pmu_access;
|
||||
bool enable_kernel_debugging;
|
||||
bool enable_dynamic_resource_limits;
|
||||
};
|
||||
private:
|
||||
static inline constinit bool s_is_uninitialized = true;
|
||||
static inline constinit bool s_is_initialized = false;
|
||||
static inline constinit const volatile KTargetSystemData s_data = {
|
||||
.is_not_debug_mode = false,
|
||||
.disable_debug_logging = false,
|
||||
.disable_user_exception_handlers = false,
|
||||
.disable_debug_memory_fill = false,
|
||||
.disable_user_pmu_access = false,
|
||||
.disable_kernel_debugging = false,
|
||||
.disable_dynamic_resource_limits = true,
|
||||
.is_debug_mode = true,
|
||||
.enable_debug_logging = true,
|
||||
.enable_user_exception_handlers = true,
|
||||
.enable_debug_memory_fill = true,
|
||||
.enable_user_pmu_access = true,
|
||||
.enable_kernel_debugging = true,
|
||||
.enable_dynamic_resource_limits = false,
|
||||
};
|
||||
private:
|
||||
static ALWAYS_INLINE void SetInitialized() { s_is_uninitialized = false; }
|
||||
static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; }
|
||||
public:
|
||||
static ALWAYS_INLINE bool IsDebugMode() { return !(s_is_uninitialized | s_data.is_not_debug_mode); }
|
||||
static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return !(s_is_uninitialized | s_data.disable_debug_logging); }
|
||||
static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return !(s_is_uninitialized | s_data.disable_user_exception_handlers); }
|
||||
static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return !(s_is_uninitialized | s_data.disable_debug_memory_fill); }
|
||||
static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return !(s_is_uninitialized | s_data.disable_user_pmu_access); }
|
||||
static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return !(s_is_uninitialized | s_data.disable_kernel_debugging); }
|
||||
static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return !(s_is_uninitialized | s_data.disable_dynamic_resource_limits); }
|
||||
static ALWAYS_INLINE bool IsDebugMode() { return s_is_initialized && s_data.is_debug_mode; }
|
||||
static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_is_initialized && s_data.enable_debug_logging; }
|
||||
static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_is_initialized && s_data.enable_user_exception_handlers; }
|
||||
static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_is_initialized && s_data.enable_debug_memory_fill; }
|
||||
static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_is_initialized && s_data.enable_user_pmu_access; }
|
||||
static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_is_initialized && s_data.enable_kernel_debugging; }
|
||||
static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_is_initialized && s_data.enable_dynamic_resource_limits; }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -109,31 +109,12 @@ namespace ams::kern::arch::arm64 {
|
||||
return insn;
|
||||
}
|
||||
|
||||
void HandleUserException(KExceptionContext *context, u64 raw_esr, u64 raw_far, u64 afsr0, u64 afsr1, u32 data) {
|
||||
/* Pre-process exception registers as needed. */
|
||||
u64 esr = raw_esr;
|
||||
u64 far = raw_far;
|
||||
const u64 ec = (esr >> 26) & 0x3F;
|
||||
if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) {
|
||||
/* Adjust registers if a synchronous external abort has occurred with far not valid. */
|
||||
/* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */
|
||||
/* not on translation table walk or hardware update of translation table. */
|
||||
/* Mask 0x400 = FnV = "FAR Not Valid" */
|
||||
/* TODO: How would we perform this check using named register accesses? */
|
||||
if ((esr & 0x43F) == 0x410) {
|
||||
/* Clear the faulting register on memory tagging exception. */
|
||||
far = 0;
|
||||
} else {
|
||||
/* If the faulting address is a kernel address, set ISFC = 4. */
|
||||
if (far >= ams::svc::AddressMemoryRegion39Size) {
|
||||
esr = (esr & 0xFFFFFFC0) | 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleUserException(KExceptionContext *context, u64 esr, u64 far, u64 afsr0, u64 afsr1, u32 data) {
|
||||
KProcess &cur_process = GetCurrentProcess();
|
||||
bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled();
|
||||
|
||||
const u64 ec = (esr >> 26) & 0x3F;
|
||||
|
||||
/* In the event that we return from this exception, we want SPSR.SS set so that we advance an instruction if single-stepping. */
|
||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||
context->psr |= (1ul << 21);
|
||||
@@ -184,7 +165,7 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
/* Save the debug parameters to the current thread. */
|
||||
GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data);
|
||||
GetCurrentThread().SaveDebugParams(far, esr, data);
|
||||
|
||||
/* Get the exception type. */
|
||||
u32 type;
|
||||
@@ -406,6 +387,7 @@ namespace ams::kern::arch::arm64 {
|
||||
ams::svc::aarch32::ExceptionInfo info32;
|
||||
} info = {};
|
||||
|
||||
|
||||
const bool is_aarch64 = (e_ctx->psr & 0x10) == 0;
|
||||
if (is_aarch64) {
|
||||
/* We're 64-bit. */
|
||||
@@ -450,28 +432,9 @@ namespace ams::kern::arch::arm64 {
|
||||
uintptr_t far, esr, data;
|
||||
GetCurrentThread().RestoreDebugParams(std::addressof(far), std::addressof(esr), std::addressof(data));
|
||||
|
||||
/* Pre-process exception registers as needed. */
|
||||
const u64 ec = (esr >> 26) & 0x3F;
|
||||
if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) {
|
||||
/* Adjust registers if a synchronous external abort has occurred with far not valid. */
|
||||
/* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */
|
||||
/* not on translation table walk or hardware update of translation table. */
|
||||
/* Mask 0x400 = FnV = "FAR Not Valid" */
|
||||
/* TODO: How would we perform this check using named register accesses? */
|
||||
if ((esr & 0x43F) == 0x410) {
|
||||
/* Clear the faulting register on memory tagging exception. */
|
||||
far = 0;
|
||||
} else {
|
||||
/* If the faulting address is a kernel address, set ISFC = 4. */
|
||||
if (far >= ams::svc::AddressMemoryRegion39Size) {
|
||||
esr = (esr & 0xFFFFFFC0) | 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Collect additional information based on the ec. */
|
||||
uintptr_t params[3] = {};
|
||||
switch (ec) {
|
||||
switch ((esr >> 26) & 0x3F) {
|
||||
case EsrEc_Unknown:
|
||||
case EsrEc_IllegalExecution:
|
||||
case EsrEc_BkptInstruction:
|
||||
|
||||
@@ -752,10 +752,13 @@ namespace ams::kern::arch::arm64 {
|
||||
while (true) {
|
||||
/* Try to merge. */
|
||||
KVirtualAddress freed_table = Null<KVirtualAddress>;
|
||||
if (!impl.MergePages(std::addressof(freed_table), context, &KPageTable::NoteUpdatedCallback, this)) {
|
||||
if (!impl.MergePages(std::addressof(freed_table), context)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Note that we updated. */
|
||||
this->NoteUpdated();
|
||||
|
||||
/* Free the page. */
|
||||
if (freed_table != Null<KVirtualAddress>) {
|
||||
ClearPageTable(freed_table);
|
||||
@@ -813,7 +816,8 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
/* Separate. */
|
||||
impl.SeparatePages(entry, context, virt_addr, GetPointer<PageTableEntry>(table), &KPageTable::NoteUpdatedCallback, this);
|
||||
impl.SeparatePages(entry, context, virt_addr, GetPointer<PageTableEntry>(table));
|
||||
this->NoteUpdated();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -1021,9 +1025,6 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Finally, apply the changes as directed, flushing the mappings before they're applied (if we should). */
|
||||
ApplyEntryTemplate(entry_template, flush_mapping ? ApplyOption_FlushDataCache : ApplyOption_None);
|
||||
|
||||
/* Wait for pending stores to complete. */
|
||||
cpu::DataSynchronizationBarrierInnerShareableStore();
|
||||
}
|
||||
|
||||
/* We've succeeded, now perform what coalescing we can. */
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace ams::kern::arch::arm64 {
|
||||
return is_block;
|
||||
}
|
||||
|
||||
bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt) {
|
||||
bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) {
|
||||
/* We want to upgrade the pages by one step. */
|
||||
if (context->is_contiguous) {
|
||||
/* We can't merge an L1 table. */
|
||||
@@ -251,7 +251,6 @@ namespace ams::kern::arch::arm64 {
|
||||
const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled());
|
||||
|
||||
*context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false, false);
|
||||
on_entry_updated(pt);
|
||||
|
||||
/* Update our context. */
|
||||
context->is_contiguous = false;
|
||||
@@ -286,7 +285,6 @@ namespace ams::kern::arch::arm64 {
|
||||
for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) {
|
||||
pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + (i << (PageBits + LevelBits * context->level)), PageTableEntry(entry_template), sw_reserved_bits, true, context->level == EntryLevel_L3);
|
||||
}
|
||||
on_entry_updated(pt);
|
||||
|
||||
/* Update our context. */
|
||||
context->level_entries[context->level] = pte;
|
||||
@@ -296,7 +294,7 @@ namespace ams::kern::arch::arm64 {
|
||||
return true;
|
||||
}
|
||||
|
||||
void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const {
|
||||
void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const {
|
||||
/* We want to downgrade the pages by one step. */
|
||||
if (context->is_contiguous) {
|
||||
/* We want to downgrade a contiguous mapping to a non-contiguous mapping. */
|
||||
@@ -307,7 +305,6 @@ namespace ams::kern::arch::arm64 {
|
||||
for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) {
|
||||
pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * context->level)), PageTableEntry(first->GetEntryTemplateForSeparateContiguous(i)), PageTableEntry::SeparateContiguousTag{});
|
||||
}
|
||||
on_entry_updated(pt);
|
||||
|
||||
context->is_contiguous = false;
|
||||
|
||||
@@ -328,12 +325,12 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Update the block entry to be a table entry. */
|
||||
*context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(pte)), m_is_kernel, true, BlocksPerTable);
|
||||
on_entry_updated(pt);
|
||||
|
||||
|
||||
context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level);
|
||||
}
|
||||
|
||||
entry->sw_reserved_bits = context->level_entries[context->level]->GetSoftwareReservedBits();
|
||||
entry->sw_reserved_bits = 0;
|
||||
entry->attr = 0;
|
||||
entry->phys_addr = this->GetBlock(context->level_entries[context->level], context->level) + this->GetOffset(address, context->level);
|
||||
entry->block_size = static_cast<size_t>(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous);
|
||||
|
||||
@@ -24,12 +24,12 @@ _ZN3ams4kern4arch5arm6432UserspaceAccessFunctionAreaBeginEv:
|
||||
|
||||
/* ================ All Userspace Access Functions after this line. ================ */
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm:
|
||||
/* Check if there's anything to copy. */
|
||||
cmp x2, #0
|
||||
b.eq 2f
|
||||
@@ -48,12 +48,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm:
|
||||
/* Check if there are 0x40 bytes to copy */
|
||||
cmp x2, #0x3F
|
||||
b.ls 1f
|
||||
@@ -72,7 +72,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv
|
||||
add x0, x0, #0x40
|
||||
add x1, x1, #0x40
|
||||
sub x2, x2, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to copy. */
|
||||
cmp x2, #0
|
||||
@@ -87,12 +87,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm:
|
||||
/* Check if there are 0x40 bytes to copy */
|
||||
cmp x2, #0x3F
|
||||
b.ls 1f
|
||||
@@ -111,7 +111,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv
|
||||
add x0, x0, #0x40
|
||||
add x1, x1, #0x40
|
||||
sub x2, x2, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to copy. */
|
||||
cmp x2, #0
|
||||
@@ -126,12 +126,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv:
|
||||
/* Just load and store a u64. */
|
||||
ldtr x2, [x1]
|
||||
str x2, [x0]
|
||||
@@ -140,12 +140,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv:
|
||||
/* Just load and store a u32. */
|
||||
ldtr w2, [x1]
|
||||
str w2, [x0]
|
||||
@@ -154,12 +154,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv:
|
||||
/* Just load and store a u32. */
|
||||
/* NOTE: This is done with supervisor access permissions. */
|
||||
ldr w2, [x1]
|
||||
@@ -169,12 +169,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSu
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringFromUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm:
|
||||
/* Check if there's anything to copy. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -204,12 +204,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm:
|
||||
mov x0, #0
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm:
|
||||
/* Check if there's anything to copy. */
|
||||
cmp x2, #0
|
||||
b.eq 2f
|
||||
@@ -228,12 +228,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm:
|
||||
/* Check if there are 0x40 bytes to copy */
|
||||
cmp x2, #0x3F
|
||||
b.ls 1f
|
||||
@@ -252,7 +252,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK
|
||||
add x0, x0, #0x40
|
||||
add x1, x1, #0x40
|
||||
sub x2, x2, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to copy. */
|
||||
cmp x2, #0
|
||||
@@ -267,12 +267,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm:
|
||||
/* Check if there are 0x40 bytes to copy */
|
||||
cmp x2, #0x3F
|
||||
b.ls 1f
|
||||
@@ -291,7 +291,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
|
||||
add x0, x0, #0x40
|
||||
add x1, x1, #0x40
|
||||
sub x2, x2, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to copy. */
|
||||
cmp x2, #0
|
||||
@@ -306,12 +306,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv:
|
||||
/* Just load and store a u32. */
|
||||
ldr w2, [x1]
|
||||
sttr w2, [x0]
|
||||
@@ -320,12 +320,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringToUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyStringToUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm:
|
||||
/* Check if there's anything to copy. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -355,12 +355,114 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm:
|
||||
mov x0, #0
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ClearMemory(void *dst, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm:
|
||||
/* Check if there's anything to clear. */
|
||||
cmp x1, #0
|
||||
b.eq 2f
|
||||
|
||||
/* Keep track of the last address. */
|
||||
add x2, x0, x1
|
||||
|
||||
1: /* We're copying memory byte-by-byte. */
|
||||
sttrb wzr, [x0]
|
||||
add x0, x0, #1
|
||||
cmp x0, x2
|
||||
b.ne 1b
|
||||
|
||||
2: /* We're done. */
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned32Bit(void *dst, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm:
|
||||
/* Check if there are 0x40 bytes to clear. */
|
||||
cmp x1, #0x3F
|
||||
b.ls 2f
|
||||
sttr xzr, [x0, #0x00]
|
||||
sttr xzr, [x0, #0x08]
|
||||
sttr xzr, [x0, #0x10]
|
||||
sttr xzr, [x0, #0x18]
|
||||
sttr xzr, [x0, #0x20]
|
||||
sttr xzr, [x0, #0x28]
|
||||
sttr xzr, [x0, #0x30]
|
||||
sttr xzr, [x0, #0x38]
|
||||
add x0, x0, #0x40
|
||||
sub x1, x1, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to clear. */
|
||||
cmp x1, #0
|
||||
b.eq 2f
|
||||
sttr wzr, [x0]
|
||||
add x0, x0, #4
|
||||
sub x1, x1, #4
|
||||
b 1b
|
||||
|
||||
2: /* We're done. */
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned64Bit(void *dst, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm:
|
||||
/* Check if there are 0x40 bytes to clear. */
|
||||
cmp x1, #0x3F
|
||||
b.ls 2f
|
||||
sttr xzr, [x0, #0x00]
|
||||
sttr xzr, [x0, #0x08]
|
||||
sttr xzr, [x0, #0x10]
|
||||
sttr xzr, [x0, #0x18]
|
||||
sttr xzr, [x0, #0x20]
|
||||
sttr xzr, [x0, #0x28]
|
||||
sttr xzr, [x0, #0x30]
|
||||
sttr xzr, [x0, #0x38]
|
||||
add x0, x0, #0x40
|
||||
sub x1, x1, #0x40
|
||||
b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm
|
||||
|
||||
1: /* We have less than 0x40 bytes to clear. */
|
||||
cmp x1, #0
|
||||
b.eq 2f
|
||||
sttr xzr, [x0]
|
||||
add x0, x0, #8
|
||||
sub x1, x1, #8
|
||||
b 1b
|
||||
|
||||
2: /* We're done. */
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ClearMemorySize32Bit(void *dst) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv:
|
||||
/* Just store a zero. */
|
||||
sttr wzr, [x0]
|
||||
|
||||
/* We're done. */
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj:
|
||||
/* Load the value from the address. */
|
||||
ldaxr w4, [x1]
|
||||
|
||||
@@ -375,7 +477,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
|
||||
stlxr w6, w5, [x1]
|
||||
|
||||
/* If we failed to store, try again. */
|
||||
cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj
|
||||
cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj
|
||||
|
||||
/* We're done. */
|
||||
str w4, [x0]
|
||||
@@ -383,12 +485,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj:
|
||||
ret
|
||||
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii:
|
||||
/* Load the value from the address. */
|
||||
ldaxr w4, [x1]
|
||||
|
||||
@@ -406,19 +508,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii:
|
||||
stlxr w5, w3, [x1]
|
||||
|
||||
/* If we failed to store, try again. */
|
||||
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii
|
||||
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii
|
||||
|
||||
2: /* We're done. */
|
||||
str w4, [x0]
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i:
|
||||
/* Load the value from the address. */
|
||||
ldaxr w3, [x1]
|
||||
|
||||
@@ -437,19 +539,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i:
|
||||
stlxr w5, w4, [x1]
|
||||
|
||||
/* If we failed to store, try again. */
|
||||
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i
|
||||
cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i
|
||||
|
||||
2: /* We're done. */
|
||||
str w3, [x0]
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::StoreDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::StoreDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x1, x0
|
||||
b.eq 2f
|
||||
@@ -464,12 +566,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::FlushDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::FlushDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x1, x0
|
||||
b.eq 2f
|
||||
@@ -484,12 +586,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::InvalidateDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::InvalidateDataCache(uintptr_t start, uintptr_t end) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x1, x0
|
||||
b.eq 2f
|
||||
@@ -504,12 +606,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -554,12 +656,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm:
|
||||
mov w9, #0xFFFFFFFF
|
||||
b 2b
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -604,12 +706,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm:
|
||||
mov w9, #0xFFFFFFFF
|
||||
b 2b
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -654,12 +756,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm:
|
||||
mov w9, #0xFFFFFFFF
|
||||
b 2b
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -699,12 +801,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
@@ -744,12 +846,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, %function
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm:
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm:
|
||||
/* Check if we have any work to do. */
|
||||
cmp x2, #0
|
||||
b.eq 3f
|
||||
|
||||
@@ -361,9 +361,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
}();
|
||||
|
||||
/* Return (possibly) adjusted size. */
|
||||
/* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */
|
||||
/* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */
|
||||
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;
|
||||
constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB;
|
||||
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
|
||||
}
|
||||
|
||||
@@ -407,22 +405,22 @@ namespace ams::kern::board::nintendo::nx {
|
||||
/* Configure KTargetSystem. */
|
||||
volatile auto *ts = const_cast<volatile KTargetSystem::KTargetSystemData *>(std::addressof(KTargetSystem::s_data));
|
||||
{
|
||||
/* Set whether we're in debug mode. */
|
||||
/* Set IsDebugMode. */
|
||||
{
|
||||
ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode);
|
||||
ts->is_debug_mode = GetConfigBool(smc::ConfigItem::IsDebugMode);
|
||||
|
||||
/* If we're not in debug mode, we don't want to initialize uart logging. */
|
||||
ts->disable_debug_logging = ts->is_not_debug_mode;
|
||||
/* If debug mode, we want to initialize uart logging. */
|
||||
ts->enable_debug_logging = ts->is_debug_mode;
|
||||
}
|
||||
|
||||
/* Set Kernel Configuration. */
|
||||
{
|
||||
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
|
||||
|
||||
ts->disable_debug_memory_fill = !kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
|
||||
ts->disable_user_exception_handlers = !kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
|
||||
ts->disable_dynamic_resource_limits = kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
|
||||
ts->disable_user_pmu_access = !kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
|
||||
ts->enable_debug_memory_fill = kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
|
||||
ts->enable_user_exception_handlers = kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
|
||||
ts->enable_dynamic_resource_limits = !kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
|
||||
ts->enable_user_pmu_access = kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
|
||||
|
||||
/* Configure call smc on panic. */
|
||||
*const_cast<volatile bool *>(std::addressof(g_call_smc_on_panic)) = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
|
||||
@@ -432,7 +430,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
{
|
||||
/* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */
|
||||
/* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */
|
||||
ts->disable_kernel_debugging = !GetConfigBool(smc::ConfigItem::DisableProgramVerification);
|
||||
ts->enable_kernel_debugging = GetConfigBool(smc::ConfigItem::DisableProgramVerification);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -526,7 +524,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
KScopedSpinLock lk(s_random_lock);
|
||||
|
||||
|
||||
if (AMS_LIKELY(!s_uninitialized_random_generator)) {
|
||||
if (AMS_LIKELY(s_initialized_random_generator)) {
|
||||
return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); });
|
||||
} else {
|
||||
return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc);
|
||||
@@ -537,7 +535,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
KScopedInterruptDisable intr_disable;
|
||||
KScopedSpinLock lk(s_random_lock);
|
||||
|
||||
if (AMS_LIKELY(!s_uninitialized_random_generator)) {
|
||||
if (AMS_LIKELY(s_initialized_random_generator)) {
|
||||
return s_random_generator.GenerateRandomU64();
|
||||
} else {
|
||||
return GenerateRandomU64FromSmc();
|
||||
|
||||
@@ -66,39 +66,12 @@ namespace ams::kern {
|
||||
|
||||
}
|
||||
|
||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type, size_t code_size) {
|
||||
MESOSPHERE_UNUSED(code_size);
|
||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress();
|
||||
}
|
||||
|
||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||
/* Extract the address space from the create process flags. */
|
||||
const auto as_flags = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
|
||||
|
||||
/* Get the address space width. */
|
||||
const auto as_width = GetAddressSpaceWidth(flags);
|
||||
|
||||
/* Get the size. */
|
||||
size_t as_size = GetAddressSpaceInfo(as_width, type).GetSize();
|
||||
|
||||
/* If we're getting size for 32-bit without alias, adjust the sizes accordingly. */
|
||||
if (as_flags == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) {
|
||||
switch (type) {
|
||||
/* The heap space receives space that would otherwise go to the alias space. */
|
||||
case KAddressSpaceInfo::Type_Heap:
|
||||
as_size += GetAddressSpaceInfo(as_width, KAddressSpaceInfo::Type_Alias).GetSize();
|
||||
break;
|
||||
/* The alias space doesn't exist. */
|
||||
case KAddressSpaceInfo::Type_Alias:
|
||||
as_size = 0;
|
||||
break;
|
||||
/* Nothing to do by default. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return as_size;
|
||||
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize();
|
||||
}
|
||||
|
||||
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
||||
|
||||
@@ -229,12 +229,9 @@ namespace ams::kern {
|
||||
out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge;
|
||||
|
||||
/* Set and check code address. */
|
||||
/* NOTE: Even though Nintendo passes a size to GetAddressSpaceStart at other call sites, they pass */
|
||||
/* a number of pages here. Even though this is presumably only used for debug assertions, this is */
|
||||
/* almost certainly a bug. */
|
||||
using ASType = KAddressSpaceInfo::Type;
|
||||
const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall;
|
||||
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type, out->code_num_pages);
|
||||
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
|
||||
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
|
||||
const uintptr_t map_end = map_start + map_size;
|
||||
out->code_address = map_start + start_address;
|
||||
|
||||
@@ -118,78 +118,29 @@ namespace ams::kern {
|
||||
MESOSPHERE_ASSERT(m_memory_block_tree.empty());
|
||||
}
|
||||
|
||||
bool KMemoryBlockManager::GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) {
|
||||
/* Check that there's room for the pages in the specified region. */
|
||||
if (num_pages + 2 * guard_pages > region_num_pages) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Determine the aligned start of the guarded region. */
|
||||
const KProcessAddress guarded_start = region_start + guard_pages * PageSize;
|
||||
const KProcessAddress aligned_guarded_start = util::AlignDown(GetInteger(guarded_start), alignment);
|
||||
KProcessAddress aligned_guarded_start_with_offset = aligned_guarded_start + offset;
|
||||
if (guarded_start > aligned_guarded_start_with_offset) {
|
||||
if (!util::CanAddWithoutOverflow<uintptr_t>(GetInteger(aligned_guarded_start), alignment)) {
|
||||
return false;
|
||||
}
|
||||
aligned_guarded_start_with_offset += alignment;
|
||||
}
|
||||
|
||||
/* Determine the aligned end of the guarded region. */
|
||||
const KProcessAddress guarded_end = region_start + ((region_num_pages - (num_pages + guard_pages)) * PageSize);
|
||||
const KProcessAddress aligned_guarded_end = util::AlignDown(GetInteger(guarded_end), alignment);
|
||||
KProcessAddress aligned_guarded_end_with_offset = aligned_guarded_end + offset;
|
||||
if (aligned_guarded_end_with_offset > guarded_end) {
|
||||
if (aligned_guarded_end < alignment) {
|
||||
return false;
|
||||
}
|
||||
aligned_guarded_end_with_offset -= alignment;
|
||||
}
|
||||
|
||||
/* Check that the extents are valid. */
|
||||
if (aligned_guarded_end_with_offset < aligned_guarded_start_with_offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set the output extents. */
|
||||
*out_start = aligned_guarded_start_with_offset;
|
||||
*out_end = aligned_guarded_end_with_offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const {
|
||||
/* Determine the range to search in. */
|
||||
KProcessAddress search_start = Null<KProcessAddress>;
|
||||
KProcessAddress search_end = Null<KProcessAddress>;
|
||||
if (this->GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) {
|
||||
/* Iterate over blocks in the search space, looking for a suitable one. */
|
||||
for (const_iterator it = this->FindIterator(search_start); it != m_memory_block_tree.cend(); it++) {
|
||||
/* If our block is past the end of our search space, we're done. */
|
||||
if (search_end < it->GetAddress()) {
|
||||
if (num_pages > 0) {
|
||||
const KProcessAddress region_end = region_start + region_num_pages * PageSize;
|
||||
const KProcessAddress region_last = region_end - 1;
|
||||
for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) {
|
||||
if (region_last < it->GetAddress()) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* We only want to consider free blocks. */
|
||||
if (it->GetState() != KMemoryState_Free) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Determine the candidate range. */
|
||||
KProcessAddress candidate_start = Null<KProcessAddress>;
|
||||
KProcessAddress candidate_end = Null<KProcessAddress>;
|
||||
if (!this->GetRegionForFindFreeArea(std::addressof(candidate_start), std::addressof(candidate_end), it->GetAddress(), it->GetNumPages(), num_pages, alignment, offset, guard_pages)) {
|
||||
continue;
|
||||
}
|
||||
KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress();
|
||||
area += guard_pages * PageSize;
|
||||
|
||||
/* Try the suggested candidate (coercing into the search region if needed). */
|
||||
KProcessAddress candidate = candidate_start;
|
||||
if (candidate < search_start) {
|
||||
candidate = search_start;
|
||||
}
|
||||
const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset;
|
||||
area = (area <= offset_area) ? offset_area : offset_area + alignment;
|
||||
|
||||
/* Check if the candidate is valid. */
|
||||
if (candidate <= search_end && candidate <= candidate_end) {
|
||||
return candidate;
|
||||
const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize;
|
||||
const KProcessAddress area_last = area_end - 1;
|
||||
|
||||
if (GetInteger(it->GetAddress()) <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= GetInteger(it->GetLastAddress())) {
|
||||
return area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace ams::kern {
|
||||
|
||||
/* Define helpers. */
|
||||
auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
||||
return KAddressSpaceInfo::GetAddressSpaceStart(flags, type, code_size);
|
||||
return KAddressSpaceInfo::GetAddressSpaceStart(flags, type);
|
||||
};
|
||||
auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
||||
return KAddressSpaceInfo::GetAddressSpaceSize(flags, type);
|
||||
@@ -155,6 +155,12 @@ namespace ams::kern {
|
||||
size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias);
|
||||
size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap);
|
||||
|
||||
/* Adjust heap/alias size if we don't have an alias region. */
|
||||
if ((flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) {
|
||||
heap_region_size += alias_region_size;
|
||||
alias_region_size = 0;
|
||||
}
|
||||
|
||||
/* Set code regions and determine remaining sizes. */
|
||||
KProcessAddress process_code_start;
|
||||
KProcessAddress process_code_end;
|
||||
@@ -1333,37 +1339,34 @@ namespace ams::kern {
|
||||
KProcessAddress KPageTableBase::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const {
|
||||
KProcessAddress address = Null<KProcessAddress>;
|
||||
|
||||
KProcessAddress search_start = Null<KProcessAddress>;
|
||||
KProcessAddress search_end = Null<KProcessAddress>;
|
||||
if (m_memory_block_manager.GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) {
|
||||
if (num_pages <= region_num_pages) {
|
||||
if (this->IsAslrEnabled()) {
|
||||
/* Try to directly find a free area up to 8 times. */
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
const size_t random_offset = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment) * alignment;
|
||||
const KProcessAddress candidate = search_start + random_offset;
|
||||
const size_t random_offset = KSystemControl::GenerateRandomRange(0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) * alignment;
|
||||
const KProcessAddress candidate = util::AlignDown(GetInteger(region_start + random_offset), alignment) + offset;
|
||||
|
||||
KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate);
|
||||
MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end());
|
||||
|
||||
if (it->GetState() != KMemoryState_Free) { continue; }
|
||||
if (!(region_start <= candidate)) { continue; }
|
||||
if (!(it->GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; }
|
||||
if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= it->GetLastAddress())) { continue; }
|
||||
if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= region_start + region_num_pages * PageSize - 1)) { continue; }
|
||||
|
||||
address = candidate;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Fall back to finding the first free area with a random offset. */
|
||||
if (address == Null<KProcessAddress>) {
|
||||
/* NOTE: Nintendo does not account for guard pages here. */
|
||||
/* This may theoretically cause an offset to be chosen that cannot be mapped. */
|
||||
/* We will account for guard pages. */
|
||||
const size_t offset_blocks = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment);
|
||||
const auto region_end = region_start + region_num_pages * PageSize;
|
||||
address = m_memory_block_manager.FindFreeArea(search_start + offset_blocks * alignment, (region_end - (search_start + offset_blocks * alignment)) / PageSize, num_pages, alignment, offset, guard_pages);
|
||||
const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages);
|
||||
address = m_memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the first free area. */
|
||||
if (address == Null<KProcessAddress>) {
|
||||
address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages, alignment, offset, guard_pages);
|
||||
@@ -1789,24 +1792,19 @@ namespace ams::kern {
|
||||
KScopedSchedulerLock sl;
|
||||
}
|
||||
|
||||
/* Ensure cache coherency, if we're setting pages as executable. */
|
||||
if (is_x) {
|
||||
for (const auto &block : pg) {
|
||||
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize());
|
||||
}
|
||||
cpu::InvalidateEntireInstructionCache();
|
||||
}
|
||||
|
||||
/* Perform mapping operation. */
|
||||
const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None };
|
||||
const auto operation = was_x ? OperationType_ChangePermissionsAndRefresh : OperationType_ChangePermissions;
|
||||
const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions;
|
||||
R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, operation, false));
|
||||
|
||||
/* Update the blocks. */
|
||||
m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None);
|
||||
|
||||
/* Ensure cache coherency, if we're setting pages as executable. */
|
||||
if (was_x) {
|
||||
if (is_x) {
|
||||
for (const auto &block : pg) {
|
||||
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize());
|
||||
}
|
||||
cpu::InvalidateEntireInstructionCache();
|
||||
}
|
||||
|
||||
@@ -2548,11 +2546,6 @@ namespace ams::kern {
|
||||
/* We're going to perform an update, so create a helper. */
|
||||
KScopedPageTableUpdater updater(this);
|
||||
|
||||
/* Ensure cache coherency, if we're mapping executable pages. */
|
||||
if ((perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) {
|
||||
cpu::InvalidateEntireInstructionCache();
|
||||
}
|
||||
|
||||
/* Perform mapping operation. */
|
||||
const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead };
|
||||
R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
|
||||
@@ -2576,9 +2569,8 @@ namespace ams::kern {
|
||||
KScopedLightLock lk(m_general_lock);
|
||||
|
||||
/* Check if state allows us to unmap. */
|
||||
KMemoryPermission old_perm;
|
||||
size_t num_allocator_blocks;
|
||||
R_TRY(this->CheckMemoryState(nullptr, std::addressof(old_perm), nullptr, std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None));
|
||||
R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None));
|
||||
|
||||
/* Check that the page group is valid. */
|
||||
R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), svc::ResultInvalidCurrentMemory());
|
||||
@@ -2595,11 +2587,6 @@ namespace ams::kern {
|
||||
const KPageProperties properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None };
|
||||
R_TRY(this->Operate(updater.GetPageList(), address, num_pages, Null<KPhysicalAddress>, false, properties, OperationType_Unmap, false));
|
||||
|
||||
/* Ensure cache coherency, if we're mapping executable pages. */
|
||||
if ((old_perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) {
|
||||
cpu::InvalidateEntireInstructionCache();
|
||||
}
|
||||
|
||||
/* Update the blocks. */
|
||||
m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal);
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* Set max memory. */
|
||||
m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(m_flags), KAddressSpaceInfo::Type_Heap);
|
||||
m_max_process_memory = m_page_table.GetHeapRegionSize();
|
||||
|
||||
/* Generate random entropy. */
|
||||
KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy));
|
||||
|
||||
@@ -102,10 +102,10 @@ namespace ams::kern {
|
||||
|
||||
/* Randomness for Initialization. */
|
||||
void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) {
|
||||
if (AMS_UNLIKELY(s_uninitialized_random_generator)) {
|
||||
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
|
||||
const u64 seed = KHardwareTimer::GetTick();
|
||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||
s_uninitialized_random_generator = false;
|
||||
s_initialized_random_generator = true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
@@ -114,10 +114,10 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) {
|
||||
if (AMS_UNLIKELY(s_uninitialized_random_generator)) {
|
||||
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
|
||||
const u64 seed = KHardwareTimer::GetTick();
|
||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||
s_uninitialized_random_generator = false;
|
||||
s_initialized_random_generator = true;
|
||||
}
|
||||
|
||||
return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); });
|
||||
@@ -140,9 +140,9 @@ namespace ams::kern {
|
||||
|
||||
void KSystemControlBase::InitializePhase1Base(u64 seed) {
|
||||
/* Initialize the rng, if we somehow haven't already. */
|
||||
if (AMS_UNLIKELY(s_uninitialized_random_generator)) {
|
||||
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
|
||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||
s_uninitialized_random_generator = false;
|
||||
s_initialized_random_generator = true;
|
||||
}
|
||||
|
||||
/* Initialize debug logging. */
|
||||
|
||||
@@ -59,9 +59,7 @@ namespace ams::kern {
|
||||
memory_reservation.Commit();
|
||||
|
||||
/* Open reference to our resource limit. */
|
||||
if (m_resource_limit != nullptr) {
|
||||
m_resource_limit->Open();
|
||||
}
|
||||
m_resource_limit->Open();
|
||||
|
||||
/* Set ourselves as initialized. */
|
||||
m_is_initialized = true;
|
||||
@@ -78,14 +76,11 @@ namespace ams::kern {
|
||||
/* Free our secure memory. */
|
||||
KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool);
|
||||
|
||||
/* Clean up our resource usage. */
|
||||
if (m_resource_limit != nullptr) {
|
||||
/* Release the memory reservation. */
|
||||
m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize());
|
||||
/* Release the memory reservation. */
|
||||
m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize());
|
||||
|
||||
/* Close reference to our resource limit. */
|
||||
m_resource_limit->Close();
|
||||
}
|
||||
/* Close reference to our resource limit. */
|
||||
m_resource_limit->Close();
|
||||
}
|
||||
|
||||
size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool) {
|
||||
|
||||
@@ -74,45 +74,43 @@ namespace ams::kern {
|
||||
MESOSPHERE_ABORT_UNLESS(rc_size < size);
|
||||
size -= rc_size;
|
||||
|
||||
/* Determine dynamic page managers. */
|
||||
KDynamicPageManager * const app_dynamic_page_manager = nullptr;
|
||||
KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
|
||||
|
||||
/* Initialize the resource managers' shared page manager. */
|
||||
g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
|
||||
|
||||
/* Initialize the KPageBuffer slab heap. */
|
||||
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);
|
||||
|
||||
/* Initialize the block info heap. */
|
||||
s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize);
|
||||
|
||||
/* Initialize the system slab managers. */
|
||||
s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap));
|
||||
s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize);
|
||||
s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap));
|
||||
|
||||
/* Initialize the application slab managers. */
|
||||
s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap));
|
||||
/* Initialize the fixed-size slabheaps. */
|
||||
s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize);
|
||||
s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap));
|
||||
s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize);
|
||||
s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize);
|
||||
|
||||
/* Reserve all but a fixed number of remaining pages for the page table heap. */
|
||||
const size_t num_pt_pages = g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() - ReservedDynamicPageCount;
|
||||
s_page_table_heap.Initialize(std::addressof(g_resource_manager_page_manager), num_pt_pages, GetPointer<KPageTableManager::RefCount>(address + size));
|
||||
|
||||
/* Create and initialize the system system resource. */
|
||||
s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap));
|
||||
KAutoObject::Create<KSystemResource>(std::addressof(s_sys_system_resource));
|
||||
s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager);
|
||||
/* Setup the slab managers. */
|
||||
KDynamicPageManager * const app_dynamic_page_manager = nullptr;
|
||||
KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
|
||||
s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap));
|
||||
s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap));
|
||||
|
||||
s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap));
|
||||
s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap));
|
||||
|
||||
/* Create and initialize the application system resource. */
|
||||
s_app_page_table_manager.Initialize(app_dynamic_page_manager, std::addressof(s_page_table_heap));
|
||||
KAutoObject::Create<KSystemResource>(std::addressof(s_app_system_resource));
|
||||
s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager);
|
||||
s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap));
|
||||
|
||||
/* Check that we have the correct number of dynamic pages available. */
|
||||
MESOSPHERE_ABORT_UNLESS(g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() == ReservedDynamicPageCount);
|
||||
|
||||
/* Create the system page table managers. */
|
||||
KAutoObject::Create<KSystemResource>(std::addressof(s_app_system_resource));
|
||||
KAutoObject::Create<KSystemResource>(std::addressof(s_sys_system_resource));
|
||||
|
||||
/* Set the managers for the system resources. */
|
||||
s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager);
|
||||
s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager);
|
||||
}
|
||||
|
||||
void Kernel::PrintLayout() {
|
||||
|
||||
@@ -109,12 +109,11 @@ namespace ams::kern::svc {
|
||||
/* Decide on an address space map region. */
|
||||
uintptr_t map_start, map_end;
|
||||
size_t map_size;
|
||||
const size_t code_size = params.code_num_pages * PageSize;
|
||||
switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) {
|
||||
case ams::svc::CreateProcessFlag_AddressSpace32Bit:
|
||||
case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias:
|
||||
{
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size);
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||
map_end = map_start + map_size;
|
||||
}
|
||||
@@ -124,7 +123,7 @@ namespace ams::kern::svc {
|
||||
/* 64-bit address space requires 64-bit process. */
|
||||
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
||||
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size);
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||
map_end = map_start + map_size;
|
||||
}
|
||||
@@ -134,7 +133,7 @@ namespace ams::kern::svc {
|
||||
/* 64-bit address space requires 64-bit process. */
|
||||
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
||||
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit, code_size);
|
||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
|
||||
map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
|
||||
|
||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Heap);
|
||||
@@ -182,6 +181,7 @@ namespace ams::kern::svc {
|
||||
const size_t code_num_pages = params.code_num_pages;
|
||||
const size_t system_resource_num_pages = params.system_resource_num_pages;
|
||||
const size_t total_pages = code_num_pages + system_resource_num_pages;
|
||||
const size_t code_size = code_num_pages * PageSize;
|
||||
const size_t system_resource_size = system_resource_num_pages * PageSize;
|
||||
const size_t total_size = code_size + system_resource_size;
|
||||
|
||||
|
||||
@@ -171,8 +171,6 @@ namespace ams::impl {
|
||||
AMS_DEFINE_SYSTEM_THREAD(21, TioServer, FileServerHtcsServer);
|
||||
AMS_DEFINE_SYSTEM_THREAD(21, TioServer, SdCardObserver);
|
||||
|
||||
AMS_DEFINE_SYSTEM_THREAD(16, memlet, Main);
|
||||
|
||||
/* ServiceProfile */
|
||||
AMS_DEFINE_SYSTEM_THREAD(-1, sprofile, IpcServer);
|
||||
|
||||
|
||||
@@ -181,13 +181,6 @@
|
||||
HANDLER(NANDTypeInfoDeprecated, 140 ) \
|
||||
HANDLER(MicroSDTypeInfo, 141 ) \
|
||||
HANDLER(AttachmentFileInfo, 142 ) \
|
||||
HANDLER(WlanInfo, 143 ) \
|
||||
HANDLER(HalfAwakeStateInfo, 144 ) \
|
||||
HANDLER(PctlSettingInfo, 145 ) \
|
||||
HANDLER(GameCardLogInfo, 146 ) \
|
||||
HANDLER(WlanIoctlErrorInfo, 147 ) \
|
||||
HANDLER(SdCardActivationInfo, 148 ) \
|
||||
HANDLER(GameCardDetailedErrorInfo, 149 ) \
|
||||
HANDLER(TestNx, 1000) \
|
||||
HANDLER(NANDTypeInfo, 1001) \
|
||||
HANDLER(NANDExtendedCsd, 1002) \
|
||||
@@ -349,7 +342,7 @@
|
||||
HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(LastDvfsThresholdTrippedDeprecated, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
@@ -455,7 +448,7 @@
|
||||
HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(OscillatorClockDeprecated, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CpuDvfsTableClocksDeprecated, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
@@ -463,8 +456,8 @@
|
||||
HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(EmcDvfsTableVoltagesDeprecated, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockEnableFlagsDeprecated, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModulePowerEnableFlagsDeprecated, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
@@ -733,7 +726,7 @@
|
||||
HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(DramIdDeprecated, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
@@ -888,44 +881,6 @@
|
||||
HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GpuCrashDumpAttachmentId, 695, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GpuCrashDumpIsAttached, 696, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(CallerIdentifier, 697, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(WlanMainState, 698, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(WlanSubState, 699, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AdspSyslogIsAttached, 702, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LastHalfAwakeTime, 703, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(LastHalfAwakeTimeAfterBackgroundTaskDone, 704, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(LastHalfAwakeTimeAfterStateUnlocked, 705, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(LastHalfAwakePowerStateMessage, 706, HalfAwakeStateInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FastlyRequestId, 707, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CloudflareCfRay, 708, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(WlanCommandEventHistory, 709, WlanInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(FsSaveDataAttributeCheckFailureCount, 710, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PctlIsRestrictionEnabled, 711, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PctlIsPairingActive, 712, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PctlSafetyLevel, 713, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PctlRatingAge, 714, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PctlRatingOrganization, 715, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PctlIsSnsPostRestricted, 716, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PctlIsFreeCommunicationRestrictedByDefault, 717, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PctlIsStereoVisionRestricted, 718, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PctlRestrictedFreeCommunicationApplicationIdList, 719, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(PctlExemptApplicationIdList, 720, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(GameCardLogEncryptionKeyIndex, 721, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardLogEncryptedKey, 722, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicHandlerLogLength, 723, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardWorkerLogLength, 724, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicHandlerLogTimeStamp, 725, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(GameCardWorkerLogTimeStamp, 726, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(GameCardEncryptedAsicHandlerLog, 727, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GameCardEncryptedWorkerLog, 728, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(WlanIoctlErrno, 729, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FsSaveDataCertificateVerificationFailureCount, 730, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(SdCardActivationMilliSeconds, 731, SdCardActivationInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(GameCardPreviousInsertedTimestamp, 734, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
@@ -954,10 +909,5 @@
|
||||
HANDLER(BluetoothLePairingInfoCount, 1025, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(OscillatorClock, 1029, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(DramId, 1030, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None )
|
||||
|
||||
|
||||
@@ -20,28 +20,26 @@
|
||||
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
||||
#include <stratosphere/time/time_steady_clock_time_point.hpp>
|
||||
|
||||
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0)
|
||||
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)
|
||||
|
||||
@@ -17,16 +17,13 @@
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
|
||||
#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out<erpt::StorageUsageStatistics> out), (out), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentListDeprecated, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0, hos::Version_19_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, GetAttachmentList, (ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_count, out_buf, report_id), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, GetReportSizeMax, (ams::sf::Out<u32> out), (out), hos::Version_20_0_0)
|
||||
|
||||
#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out<erpt::StorageUsageStatistics> out), (out), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentList, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F)
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 16.2.0.0 */
|
||||
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id);
|
||||
|
||||
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific);
|
||||
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific);
|
||||
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -150,8 +150,7 @@ namespace ams::fssrv {
|
||||
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id);
|
||||
Result OpenCodeFileSystemDeprecated2(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id);
|
||||
Result OpenCodeFileSystemDeprecated3(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id);
|
||||
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id);
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id);
|
||||
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id);
|
||||
};
|
||||
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
|
||||
@@ -175,16 +174,11 @@ namespace ams::fssrv {
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
}
|
||||
|
||||
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
AMS_UNUSED(out_fs, out_verif, path, attr, program_id);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
}
|
||||
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
}
|
||||
|
||||
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
|
||||
AMS_UNUSED(out, process_id);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
|
||||
@@ -21,13 +21,12 @@
|
||||
#include <stratosphere/fs/fs_content_attributes.hpp>
|
||||
|
||||
/* ACCURATE_TO_VERSION: 17.5.0.0 */
|
||||
#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated4, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0, hos::Version_19_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id), (out_fs, out_verif, attr, program_id, storage_id), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out<bool> out, u64 process_id), (out, process_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0)
|
||||
#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out<bool> out, u64 process_id), (out, process_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0)
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IFileSystemProxyForLoader, AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO, 0xDC92EE15)
|
||||
|
||||
@@ -83,12 +83,8 @@ namespace ams::hos {
|
||||
Version_17_0_0 = ::ams::TargetFirmware_17_0_0,
|
||||
Version_17_0_1 = ::ams::TargetFirmware_17_0_1,
|
||||
Version_18_0_0 = ::ams::TargetFirmware_18_0_0,
|
||||
Version_18_0_1 = ::ams::TargetFirmware_18_0_1,
|
||||
Version_18_1_0 = ::ams::TargetFirmware_18_1_0,
|
||||
Version_19_0_0 = ::ams::TargetFirmware_19_0_0,
|
||||
Version_19_0_1 = ::ams::TargetFirmware_19_0_1,
|
||||
Version_20_0_0 = ::ams::TargetFirmware_20_0_0,
|
||||
Version_20_0_1 = ::ams::TargetFirmware_20_0_1,
|
||||
|
||||
Version_Current = ::ams::TargetFirmware_Current,
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
#include <stratosphere/ldr/ldr_types.hpp>
|
||||
#include <stratosphere/sf.hpp>
|
||||
|
||||
#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ldr::ProgramAttributes &attrs), (proc_h, id, flags, std::move(reslimit_h), attrs)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, loc, attrs)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out<ldr::PinId> out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out<bool> out, ncm::ProgramId program_id), (out, program_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, out_status, loc, attrs)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out<ldr::PinId> out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status))
|
||||
#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h), (proc_h, id, flags, std::move(reslimit_h))) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out<ldr::PinId> out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out<bool> out, ncm::ProgramId program_id), (out, program_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out<ldr::ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out<ldr::PinId> out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status))
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ldr::impl, IProcessManagerInterface, AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO, 0x01518B8E)
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
namespace ams::ldr::pm {
|
||||
|
||||
/* Process Manager API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit, ldr::ProgramAttributes attrs);
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs);
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit);
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc);
|
||||
Result UnpinProgram(PinId pin_id);
|
||||
Result SetEnabledProgramVerification(bool enabled);
|
||||
Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id);
|
||||
|
||||
/* Atmosphere extension API. */
|
||||
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs);
|
||||
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc);
|
||||
Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <stratosphere/ncm/ncm_program_location.hpp>
|
||||
#include <stratosphere/sf/sf_buffer_tags.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_platform.hpp>
|
||||
#include <stratosphere/fs/fs_content_attributes.hpp>
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
@@ -266,10 +265,4 @@ namespace ams::ldr {
|
||||
};
|
||||
static_assert(sizeof(Npdm) == 0x80 && util::is_pod<Npdm>::value, "Npdm definition!");
|
||||
|
||||
struct ProgramAttributes {
|
||||
ncm::ContentMetaPlatform platform;
|
||||
fs::ContentAttributes content_attributes;
|
||||
};
|
||||
static_assert(sizeof(ProgramAttributes) == 2 && util::is_pod<ProgramAttributes>::value, "ProgramAttributes definition!");
|
||||
|
||||
}
|
||||
|
||||
@@ -226,11 +226,6 @@ namespace ams::ncm {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetPlatform(out, key));
|
||||
}
|
||||
|
||||
Result HasAttributes(u8 *out, u8 attr_mask) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->HasAttributes(out, attr_mask));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out<u8> out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out<ncm::ContentMetaPlatform> out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, HasAttributes, (sf::Out<u8> out, u8 attr_mask), (out, attr_mask), hos::Version_20_0_0)
|
||||
AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out<ncm::ContentMetaPlatform> out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC)
|
||||
|
||||
@@ -72,7 +72,6 @@ namespace ams::ncm {
|
||||
Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type);
|
||||
Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset);
|
||||
Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key);
|
||||
Result HasAttributes(sf::Out<u8> out, u8 attr_mask);
|
||||
};
|
||||
static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>);
|
||||
|
||||
|
||||
@@ -121,15 +121,13 @@ namespace ams::ncm {
|
||||
|
||||
static const AtmosphereProgramId Mitm;
|
||||
static const AtmosphereProgramId AtmosphereLogManager;
|
||||
static const AtmosphereProgramId AtmosphereMemlet;
|
||||
};
|
||||
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul };
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul };
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereMemlet = { 0x0100000000000421ul };
|
||||
|
||||
inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) {
|
||||
return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager || program_id == AtmosphereProgramId::AtmosphereMemlet;
|
||||
return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager;
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &) {
|
||||
|
||||
@@ -450,9 +450,6 @@ namespace ams::boot2 {
|
||||
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Migration, ncm::StorageId::BuiltInSystem), 0);
|
||||
}
|
||||
|
||||
/* Launch atmosphere's applet memory service program. */
|
||||
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::AtmosphereProgramId::AtmosphereMemlet, ncm::StorageId::None), 0);
|
||||
|
||||
/* Launch user programs off of the SD. */
|
||||
LaunchFlaggedProgramsOnSdCard();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ams::erpt::srv {
|
||||
R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument());
|
||||
R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument());
|
||||
|
||||
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags, nullptr));
|
||||
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags));
|
||||
|
||||
ManagerImpl::NotifyAll();
|
||||
|
||||
@@ -142,11 +142,6 @@ namespace ams::erpt::srv {
|
||||
R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size));
|
||||
}
|
||||
|
||||
Result ContextImpl::SubmitAttachmentWithLz4Compression(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) {
|
||||
/* TODO: Implement LZ4 compression on attachments. */
|
||||
R_RETURN(this->SubmitAttachment(out, attachment_name, attachment_data));
|
||||
}
|
||||
|
||||
Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags) {
|
||||
const ContextEntry *ctx = reinterpret_cast<const ContextEntry *>( ctx_buffer.GetPointer());
|
||||
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
|
||||
@@ -159,7 +154,7 @@ namespace ams::erpt::srv {
|
||||
R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument());
|
||||
R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument());
|
||||
|
||||
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags, nullptr));
|
||||
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags));
|
||||
|
||||
ManagerImpl::NotifyAll();
|
||||
|
||||
@@ -174,29 +169,6 @@ namespace ams::erpt::srv {
|
||||
R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess()));
|
||||
}
|
||||
|
||||
Result ContextImpl::CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id) {
|
||||
const ContextEntry *ctx = reinterpret_cast<const ContextEntry *>( ctx_buffer.GetPointer());
|
||||
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
|
||||
const ReportMetaData *meta = reinterpret_cast<const ReportMetaData *>(meta_buffer.GetPointer());
|
||||
|
||||
const u32 ctx_size = static_cast<u32>(ctx_buffer.GetSize());
|
||||
const u32 data_size = static_cast<u32>(data_buffer.GetSize());
|
||||
const u32 meta_size = static_cast<u32>(meta_buffer.GetSize());
|
||||
|
||||
const AttachmentId *attachments = reinterpret_cast<const AttachmentId *>(attachment_ids_buffer.GetPointer());
|
||||
const u32 num_attachments = attachment_ids_buffer.GetSize() / sizeof(*attachments);
|
||||
|
||||
R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument());
|
||||
R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument());
|
||||
R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument());
|
||||
|
||||
R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, attachments, num_attachments, flags, std::addressof(report_id)));
|
||||
|
||||
ManagerImpl::NotifyAll();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) {
|
||||
R_RETURN(Reporter::RegisterRunningApplet(program_id));
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@ namespace ams::erpt::srv {
|
||||
Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags);
|
||||
Result CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result);
|
||||
Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags);
|
||||
Result SubmitAttachmentWithLz4Compression(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data);
|
||||
Result CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_data, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id);
|
||||
Result RegisterRunningApplet(ncm::ProgramId program_id);
|
||||
Result UnregisterRunningApplet(ncm::ProgramId program_id);
|
||||
Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration);
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace ams::erpt::srv {
|
||||
R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str)));
|
||||
|
||||
/* Create report. */
|
||||
R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags(), nullptr));
|
||||
R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags()));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace ams::erpt::srv {
|
||||
R_RETURN(JournalForReports::DeleteReport(report_id));
|
||||
}
|
||||
|
||||
Result Journal::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) {
|
||||
R_RETURN(JournalForAttachments::GetAttachmentList(out_count, out_infos, max_out_infos, report_id));
|
||||
Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) {
|
||||
R_RETURN(JournalForAttachments::GetAttachmentList(out, report_id));
|
||||
}
|
||||
|
||||
util::Uuid Journal::GetJournalId() {
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace ams::erpt::srv {
|
||||
static void CleanupAttachments();
|
||||
static Result CommitJournal(Stream *stream);
|
||||
static Result DeleteAttachments(ReportId report_id);
|
||||
static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id);
|
||||
static Result GetAttachmentList(AttachmentList *out, ReportId report_id);
|
||||
static u32 GetUsedStorage();
|
||||
static Result RestoreJournal(Stream *stream);
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace ams::erpt::srv {
|
||||
static void CleanupReports();
|
||||
static Result Commit();
|
||||
static Result Delete(ReportId report_id);
|
||||
static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id);
|
||||
static Result GetAttachmentList(AttachmentList *out, ReportId report_id);
|
||||
static util::Uuid GetJournalId();
|
||||
static s64 GetMaxReportSize();
|
||||
static Result GetReportList(ReportList *out, ReportType type_filter);
|
||||
|
||||
@@ -77,19 +77,14 @@ namespace ams::erpt::srv {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result JournalForAttachments::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) {
|
||||
if (hos::GetVersion() >= hos::Version_20_0_0) {
|
||||
/* TODO: What define gives a minimum of 10? */
|
||||
R_UNLESS(max_out_infos >= 10, erpt::ResultInvalidArgument());
|
||||
}
|
||||
|
||||
Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) {
|
||||
u32 count = 0;
|
||||
for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < max_out_infos; it++) {
|
||||
for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < util::size(out->attachments); it++) {
|
||||
if (report_id == it->m_info.owner_report_id) {
|
||||
out_infos[count++] = it->m_info;
|
||||
out->attachments[count++] = it->m_info;
|
||||
}
|
||||
}
|
||||
*out_count = count;
|
||||
out->attachment_count = count;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,23 +86,10 @@ namespace ams::erpt::srv {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ManagerImpl::GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_list, const ReportId &report_id) {
|
||||
Result ManagerImpl::GetAttachmentList(const ams::sf::OutBuffer &out_list, const ReportId &report_id) {
|
||||
R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument());
|
||||
|
||||
auto *attachment_list = reinterpret_cast<AttachmentList *>(out_list.GetPointer());
|
||||
|
||||
R_RETURN(Journal::GetAttachmentList(std::addressof(attachment_list->attachment_count), attachment_list->attachments, util::size(attachment_list->attachments), report_id));
|
||||
}
|
||||
|
||||
Result ManagerImpl::GetAttachmentList(ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id) {
|
||||
R_RETURN(Journal::GetAttachmentList(out_count.GetPointer(), reinterpret_cast<AttachmentInfo *>(out_buf.GetPointer()), out_buf.GetSize() / sizeof(AttachmentInfo), report_id));
|
||||
}
|
||||
|
||||
Result ManagerImpl::GetReportSizeMax(ams::sf::Out<u32> out) {
|
||||
/* TODO: Where is this size defined? */
|
||||
constexpr size_t ReportSizeMax = 0x3FF4F;
|
||||
*out = ReportSizeMax;
|
||||
R_SUCCEED();
|
||||
R_RETURN(Journal::GetAttachmentList(reinterpret_cast<AttachmentList *>(out_list.GetPointer()), report_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ namespace ams::erpt::srv {
|
||||
Result CleanupReports();
|
||||
Result DeleteReport(const ReportId &report_id);
|
||||
Result GetStorageUsageStatistics(ams::sf::Out<StorageUsageStatistics> out);
|
||||
Result GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
|
||||
Result GetAttachmentList(ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
|
||||
Result GetReportSizeMax(ams::sf::Out<u32> out);
|
||||
Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id);
|
||||
};
|
||||
static_assert(erpt::sf::IsIManager<ManagerImpl>);
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace ams::erpt::srv {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) {
|
||||
/* Create a context record for the report. */
|
||||
auto record = std::make_unique<ContextRecord>();
|
||||
R_UNLESS(record != nullptr, erpt::ResultOutOfMemory());
|
||||
@@ -423,10 +423,10 @@ namespace ams::erpt::srv {
|
||||
R_TRY(record->Initialize(ctx, data, data_size));
|
||||
|
||||
/* Create the report. */
|
||||
R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags, specified_report_id));
|
||||
R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags));
|
||||
}
|
||||
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) {
|
||||
/* Clear the automatic categories, when we're done with our report. */
|
||||
ON_SCOPE_EXIT {
|
||||
Context::ClearContext(CategoryId_ErrorInfo);
|
||||
@@ -444,7 +444,7 @@ namespace ams::erpt::srv {
|
||||
R_TRY(SubmitReportDefaults(ctx));
|
||||
|
||||
/* Generate report id. */
|
||||
const ReportId report_id = specified_report_id ? *specified_report_id : ReportId{ .uuid = util::GenerateUuid() };
|
||||
const ReportId report_id = { .uuid = util::GenerateUuid() };
|
||||
|
||||
/* Get posix timestamps. */
|
||||
time::PosixTime timestamp_user;
|
||||
|
||||
@@ -58,8 +58,8 @@ namespace ams::erpt::srv {
|
||||
private:
|
||||
static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp, erpt::CreateReportOptionFlagSet flags);
|
||||
public:
|
||||
static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id);
|
||||
static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id);
|
||||
static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags);
|
||||
static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ams::fs {
|
||||
return GetReference(g_stratosphere_romfs_fs);
|
||||
}
|
||||
|
||||
Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
/* Print a path suitable for the remote service. */
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path));
|
||||
@@ -79,11 +79,7 @@ namespace ams::fs {
|
||||
R_TRY(fsp->SetCurrentProcess({}));
|
||||
|
||||
sf::SharedPointer<fssrv::sf::IFileSystem> fs;
|
||||
if (hos::GetVersion() >= hos::Version_20_0_0) {
|
||||
R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), attr, program_id, storage_id));
|
||||
} else {
|
||||
R_TRY(fsp->OpenCodeFileSystemDeprecated4(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id));
|
||||
}
|
||||
R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id));
|
||||
|
||||
/* Allocate a new filesystem wrapper. */
|
||||
auto fsa = std::make_unique<impl::FileSystemServiceObjectAdapter>(std::move(fs));
|
||||
@@ -152,7 +148,7 @@ namespace ams::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr<fsa::IFileSystem> *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
/* If we can open an sd card code fs, use it. */
|
||||
R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id)));
|
||||
|
||||
@@ -160,7 +156,7 @@ namespace ams::fs {
|
||||
R_SUCCEED_IF(R_SUCCEEDED(OpenStratosphereCodeFileSystemImpl(out, program_id)));
|
||||
|
||||
/* Otherwise, fall back to a normal code fs. */
|
||||
R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id, storage_id));
|
||||
R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id));
|
||||
}
|
||||
|
||||
Result OpenHblCodeFileSystemImpl(std::unique_ptr<fsa::IFileSystem> *out) {
|
||||
@@ -338,12 +334,11 @@ namespace ams::fs {
|
||||
util::optional<SdCardRedirectionCodeFileSystem> m_code_fs;
|
||||
util::optional<ReadOnlyFileSystem> m_hbl_fs;
|
||||
ncm::ProgramId m_program_id;
|
||||
ncm::StorageId m_storage_id;
|
||||
bool m_initialized;
|
||||
public:
|
||||
AtmosphereCodeFileSystem() : m_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) {
|
||||
Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) {
|
||||
AMS_ABORT_UNLESS(!m_initialized);
|
||||
|
||||
/* If we're hbl, we need to open a hbl fs. */
|
||||
@@ -355,11 +350,10 @@ namespace ams::fs {
|
||||
|
||||
/* Open the code filesystem. */
|
||||
std::unique_ptr<fsa::IFileSystem> fsa;
|
||||
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id, storage_id));
|
||||
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id));
|
||||
m_code_fs.emplace(std::move(fsa), program_id, is_specific);
|
||||
|
||||
m_program_id = program_id;
|
||||
m_storage_id = storage_id;
|
||||
m_program_id = program_id;
|
||||
m_initialized = true;
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -392,7 +386,7 @@ namespace ams::fs {
|
||||
|
||||
}
|
||||
|
||||
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
auto mount_impl = [=]() -> Result {
|
||||
/* Clear the output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
@@ -405,7 +399,7 @@ namespace ams::fs {
|
||||
|
||||
/* Open the code file system. */
|
||||
std::unique_ptr<fsa::IFileSystem> fsa;
|
||||
R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id));
|
||||
R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id));
|
||||
|
||||
/* Register. */
|
||||
R_RETURN(fsa::Register(name, std::move(fsa)));
|
||||
@@ -420,7 +414,7 @@ namespace ams::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) {
|
||||
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) {
|
||||
auto mount_impl = [=]() -> Result {
|
||||
/* Clear the output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
@@ -436,7 +430,7 @@ namespace ams::fs {
|
||||
R_UNLESS(ams_code_fs != nullptr, fs::ResultAllocationMemoryFailedInCodeA());
|
||||
|
||||
/* Initialize the code file system. */
|
||||
R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, storage_id, is_hbl, is_specific));
|
||||
R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, is_hbl, is_specific));
|
||||
|
||||
/* Register. */
|
||||
R_RETURN(fsa::Register(name, std::move(ams_code_fs)));
|
||||
@@ -451,7 +445,7 @@ namespace ams::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
auto mount_impl = [=]() -> Result {
|
||||
/* Clear the output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
@@ -464,7 +458,7 @@ namespace ams::fs {
|
||||
|
||||
/* Open the code file system. */
|
||||
std::unique_ptr<fsa::IFileSystem> fsa;
|
||||
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id));
|
||||
R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id));
|
||||
|
||||
/* Create a wrapper fs. */
|
||||
auto wrap_fsa = std::make_unique<SdCardRedirectionCodeFileSystem>(std::move(fsa), program_id, false);
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ams::fs {
|
||||
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
|
||||
::FsCodeInfo dummy;
|
||||
::FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
|
||||
R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
|
||||
|
||||
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
|
||||
R_SUCCEED();
|
||||
@@ -41,7 +41,7 @@ namespace ams::fs {
|
||||
|
||||
Result OpenCodeFileSystemDeprecated2(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
|
||||
::FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(fs::ContentAttributes_None)), std::addressof(fs)));
|
||||
|
||||
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
|
||||
R_SUCCEED();
|
||||
@@ -49,23 +49,15 @@ namespace ams::fs {
|
||||
|
||||
Result OpenCodeFileSystemDeprecated3(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
::FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
|
||||
|
||||
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
::FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
|
||||
|
||||
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
::FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, static_cast<::NcmStorageId>(static_cast<u8>(storage_id)), nullptr, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
|
||||
R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr)), std::addressof(fs)));
|
||||
|
||||
out_fs.SetValue(ObjectFactory::CreateSharedEmplaced<fssrv::sf::IFileSystem, fssrv::impl::RemoteFileSystem>(fs));
|
||||
R_SUCCEED();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ams::fs::impl {
|
||||
#define ADD_ENUM_CASE(v) case v: return #v
|
||||
|
||||
template<> const char *IdString::ToString<pkg1::KeyGeneration>(pkg1::KeyGeneration id) {
|
||||
static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_20_0_0);
|
||||
static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_19_0_0);
|
||||
switch (id) {
|
||||
using enum pkg1::KeyGeneration;
|
||||
case KeyGeneration_1_0_0: return "1.0.0-2.3.0";
|
||||
@@ -42,8 +42,7 @@ namespace ams::fs::impl {
|
||||
case KeyGeneration_16_0_0: return "16.0.0-16.0.3";
|
||||
case KeyGeneration_17_0_0: return "17.0.0-17.0.1";
|
||||
case KeyGeneration_18_0_0: return "18.0.0-18.1.0";
|
||||
case KeyGeneration_19_0_0: return "19.0.0-19.0.1";
|
||||
case KeyGeneration_20_0_0: return "20.0.0-";
|
||||
case KeyGeneration_19_0_0: return "19.0.0-";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,16 +482,11 @@ namespace ams::fssrv {
|
||||
AMS_UNUSED(out_fs, out_verif, path, attr, program_id);
|
||||
}
|
||||
|
||||
Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated4(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) {
|
||||
AMS_ABORT("TODO");
|
||||
AMS_UNUSED(out_fs, out_verif, path, attr, program_id);
|
||||
}
|
||||
|
||||
Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) {
|
||||
AMS_ABORT("TODO");
|
||||
AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id);
|
||||
}
|
||||
|
||||
Result FileSystemProxyImpl::IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
|
||||
AMS_ABORT("TODO");
|
||||
AMS_UNUSED(out, process_id);
|
||||
|
||||
@@ -32,14 +32,8 @@ Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) {
|
||||
return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id);
|
||||
}
|
||||
|
||||
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr) {
|
||||
const struct {
|
||||
LoaderProgramAttributes attr;
|
||||
u16 pad1;
|
||||
u32 pad2;
|
||||
NcmProgramLocation loc;
|
||||
} in = { *attr, 0, 0, *loc };
|
||||
return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, in, *out_status,
|
||||
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) {
|
||||
return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status,
|
||||
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
|
||||
.buffers = { { out_program_info, sizeof(*out_program_info) } },
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ typedef struct {
|
||||
Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id);
|
||||
Result ldrDmntAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id);
|
||||
|
||||
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr);
|
||||
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc);
|
||||
Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -19,14 +19,13 @@
|
||||
namespace ams::ldr::pm {
|
||||
|
||||
/* Information API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit, ldr::ProgramAttributes attrs) {
|
||||
static_assert(sizeof(attrs) == sizeof(::LoaderProgramAttributes));
|
||||
R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs)), out));
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) {
|
||||
R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, out));
|
||||
}
|
||||
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) {
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) {
|
||||
static_assert(sizeof(*out) == sizeof(LoaderProgramInfo));
|
||||
R_RETURN(ldrPmGetProgramInfo(reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs)), reinterpret_cast<LoaderProgramInfo *>(out)));
|
||||
R_RETURN(ldrPmGetProgramInfo(reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<LoaderProgramInfo *>(out)));
|
||||
}
|
||||
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) {
|
||||
@@ -42,10 +41,10 @@ namespace ams::ldr::pm {
|
||||
R_RETURN(ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast<u64>(program_id)));
|
||||
}
|
||||
|
||||
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) {
|
||||
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
|
||||
static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!");
|
||||
static_assert(sizeof(*out) == sizeof(LoaderProgramInfo));
|
||||
R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast<LoaderProgramInfo *>(out), reinterpret_cast<CfgOverrideStatus *>(out_status), reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc)), reinterpret_cast<const ::LoaderProgramAttributes *>(std::addressof(attrs))));
|
||||
R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast<LoaderProgramInfo *>(out), reinterpret_cast<CfgOverrideStatus *>(out_status), reinterpret_cast<const NcmProgramLocation *>(std::addressof(loc))));
|
||||
}
|
||||
|
||||
Result SetEnabledProgramVerification(bool enabled) {
|
||||
|
||||
@@ -534,34 +534,4 @@ namespace ams::ncm {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentMetaDatabaseImpl::HasAttributes(sf::Out<u8> out, u8 attribute_mask) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
|
||||
/* Create a variable to hold the combined attributes. */
|
||||
u8 combined_attributes = 0;
|
||||
|
||||
/* Iterate over all entries. */
|
||||
for (auto &entry : *m_kvs) {
|
||||
/* Obtain the content meta for the key. */
|
||||
const void *meta;
|
||||
size_t meta_size;
|
||||
R_TRY(this->GetContentMetaPointer(&meta, &meta_size, entry.GetKey()));
|
||||
|
||||
/* Create a reader. */
|
||||
ContentMetaReader reader(meta, meta_size);
|
||||
|
||||
/* Accumulate the set attributes from the current entry. */
|
||||
combined_attributes |= (reader.GetHeader()->attributes) & attribute_mask;
|
||||
|
||||
/* If all the attributes we're looking for have been found, we're done. */
|
||||
if ((combined_attributes & attribute_mask) == attribute_mask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the output. */
|
||||
*out = combined_attributes;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ namespace ams::ncm {
|
||||
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) override;
|
||||
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override;
|
||||
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) override;
|
||||
virtual Result HasAttributes(sf::Out<u8> out, u8 attr_mask) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ namespace ams::ncm {
|
||||
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) = 0;
|
||||
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0;
|
||||
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) = 0;
|
||||
virtual Result HasAttributes(sf::Out<u8> out, u8 attr_mask) = 0;
|
||||
};
|
||||
static_assert(ncm::IsIContentMetaDatabase<ContentMetaDatabaseImplBase>);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -191,12 +191,6 @@ namespace ams::ncm {
|
||||
static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8));
|
||||
R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast<u8 *>(out.GetPointer()), Convert(key)));
|
||||
}
|
||||
|
||||
Result HasAttributes(sf::Out<u8> out, u8 attr_mask) {
|
||||
/* TODO: libnx bindings */
|
||||
AMS_UNUSED(out, attr_mask);
|
||||
AMS_ABORT();
|
||||
}
|
||||
};
|
||||
static_assert(ncm::IsIContentMetaDatabase<RemoteContentMetaDatabaseImpl>);
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace ams::os::impl {
|
||||
R_TRY_CATCH(svc::CreateSharedMemory(std::addressof(handle), size, svc_my_perm, svc_other_perm)) {
|
||||
R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles())
|
||||
R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfResource())
|
||||
R_CONVERT(svc::ResultLimitReached, os::ResultOutOfMemory())
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
*out = handle;
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#pragma once
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 9
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 8
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 0
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
||||
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 19
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
||||
|
||||
@@ -81,14 +81,10 @@
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_18_0_1 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 1)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_19_0_0 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_19_0_1 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 1)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_20_0_1 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 1)
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_1
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_19_0_0
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||
@@ -162,12 +158,8 @@ namespace ams {
|
||||
TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0,
|
||||
TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1,
|
||||
TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0,
|
||||
TargetFirmware_18_0_1 = ATMOSPHERE_TARGET_FIRMWARE_18_0_1,
|
||||
TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0,
|
||||
TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_0,
|
||||
TargetFirmware_19_0_1 = ATMOSPHERE_TARGET_FIRMWARE_19_0_1,
|
||||
TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0,
|
||||
TargetFirmware_20_0_1 = ATMOSPHERE_TARGET_FIRMWARE_20_0_1,
|
||||
|
||||
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
||||
|
||||
|
||||
@@ -21,20 +21,20 @@ R_DEFINE_NAMESPACE_RESULT_MODULE(ams::ldr, 9);
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1);
|
||||
R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2);
|
||||
R_DEFINE_ERROR_RESULT(MetaOverflow, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNso, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 6);
|
||||
R_DEFINE_ERROR_RESULT(MaxProcess, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotPinned, 8);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12);
|
||||
R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1);
|
||||
R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2);
|
||||
R_DEFINE_ERROR_RESULT(MetaOverflow, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNso, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 6);
|
||||
R_DEFINE_ERROR_RESULT(MaxProcess, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotPinned, 8);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramAttributes, 14);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNroImage, 52);
|
||||
|
||||
@@ -112,14 +112,6 @@ _ZN3ams4kern4init10StartCore0Emm:
|
||||
#endif
|
||||
|
||||
2: /* We're EL1. */
|
||||
/* Flush the entire data cache and invalidate the entire TLB. */
|
||||
bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
|
||||
|
||||
/* Invalidate the instruction cache, and ensure instruction consistency. */
|
||||
ic ialluis
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
/* Disable the MMU/Caches. */
|
||||
bl _ZN3ams4kern4init19DisableMmuAndCachesEv
|
||||
|
||||
@@ -154,15 +146,11 @@ _ZN3ams4kern4init10StartCore0Emm:
|
||||
/* Save the offset to virtual address from this page's physical address for our use. */
|
||||
mov x24, x1
|
||||
|
||||
/* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */
|
||||
mov x18, #0
|
||||
|
||||
/* At this point kernelldr has been invoked, and we are relocated at a random virtual address. */
|
||||
/* Next thing to do is to set up our memory management and slabheaps -- all the other core initialization. */
|
||||
/* Call ams::kern::init::InitializeCore(uintptr_t, void **) */
|
||||
mov x1, x0 /* Kernelldr returns a state object for the kernel to re-use. */
|
||||
mov x0, x21 /* Use the address we determined earlier. */
|
||||
nop
|
||||
INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase1EmPPv)
|
||||
|
||||
/* Get the init arguments for core 0. */
|
||||
@@ -176,7 +164,6 @@ _ZN3ams4kern4init10StartCore0Emm:
|
||||
|
||||
/* Perform further initialization with the stack pointer set up, as required. */
|
||||
/* This will include e.g. unmapping the identity mapping. */
|
||||
nop
|
||||
INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase2Ev)
|
||||
|
||||
/* Get the init arguments for core 0. */
|
||||
@@ -233,14 +220,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
|
||||
#endif
|
||||
|
||||
2: /* We're EL1. */
|
||||
/* Flush the entire data cache and invalidate the entire TLB. */
|
||||
bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
|
||||
|
||||
/* Invalidate the instruction cache, and ensure instruction consistency. */
|
||||
ic ialluis
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
/* Disable the MMU/Caches. */
|
||||
bl _ZN3ams4kern4init19DisableMmuAndCachesEv
|
||||
|
||||
@@ -262,7 +241,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
|
||||
b.eq 3f
|
||||
b 4f
|
||||
3: /* We're running on a Cortex-A53/Cortex-A57. */
|
||||
/* NOTE: Nintendo compares these values instead of setting them, infinite looping on incorrect value. */
|
||||
ldr x1, [x20, #(INIT_ARGUMENTS_CPUACTLR)]
|
||||
msr cpuactlr_el1, x1
|
||||
ldr x1, [x20, #(INIT_ARGUMENTS_CPUECTLR)]
|
||||
@@ -287,9 +265,6 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE:
|
||||
/* Set the stack pointer. */
|
||||
mov sp, x2
|
||||
|
||||
/* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */
|
||||
mov x18, #0
|
||||
|
||||
/* Invoke the entrypoint. */
|
||||
blr x1
|
||||
|
||||
@@ -413,6 +388,14 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv:
|
||||
/* The stack isn't set up, so we'll need to trash a register. */
|
||||
mov x22, x30
|
||||
|
||||
/* Flush the entire data cache and invalidate the entire TLB. */
|
||||
bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
|
||||
|
||||
/* Invalidate the instruction cache, and ensure instruction consistency. */
|
||||
ic ialluis
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
/* Set SCTLR_EL1 to disable the caches and mmu. */
|
||||
/* SCTLR_EL1: */
|
||||
/* - M = 0 */
|
||||
@@ -430,44 +413,27 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv:
|
||||
mov x30, x22
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */
|
||||
.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
|
||||
.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function
|
||||
_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv:
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */
|
||||
.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
|
||||
.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function
|
||||
_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv:
|
||||
/* The stack isn't set up, so we'll need to trash a register. */
|
||||
mov x24, x30
|
||||
mov x23, x30
|
||||
|
||||
/* CacheLineIdAccessor clidr_el1; */
|
||||
mrs x10, clidr_el1
|
||||
/* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */
|
||||
ubfx x9, x10, #0x15, 3
|
||||
/* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */
|
||||
ubfx x10, x10, #0x18, 3
|
||||
/* Ensure that the cache is coherent. */
|
||||
bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
|
||||
|
||||
/* int level = levels_of_unification */
|
||||
bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
|
||||
|
||||
/* while (level <= levels_of_coherency) { */
|
||||
cmp w9, w10
|
||||
b.hi 1f
|
||||
bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
|
||||
|
||||
0:
|
||||
/* FlushEntireDataCacheImplWithoutStack(level); */
|
||||
mov w0, w9
|
||||
bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv
|
||||
|
||||
/* level++; */
|
||||
cmp w9, w10
|
||||
add w9, w9, #1
|
||||
|
||||
/* } */
|
||||
b.cc 0b
|
||||
|
||||
/* cpu::DataSynchronizationBarrier(); */
|
||||
/* Invalidate the entire TLB, and ensure instruction consistency. */
|
||||
tlbi vmalle1is
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
1:
|
||||
mov x30, x24
|
||||
mov x30, x23
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheLocalWithoutStack() */
|
||||
@@ -509,27 +475,44 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv:
|
||||
mov x30, x24
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */
|
||||
.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv
|
||||
.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function
|
||||
_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv:
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */
|
||||
.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
|
||||
.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function
|
||||
_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv:
|
||||
/* The stack isn't set up, so we'll need to trash a register. */
|
||||
mov x23, x30
|
||||
mov x24, x30
|
||||
|
||||
/* Ensure that the cache is coherent. */
|
||||
bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
|
||||
/* CacheLineIdAccessor clidr_el1; */
|
||||
mrs x10, clidr_el1
|
||||
/* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */
|
||||
ubfx x9, x10, #0x15, 3
|
||||
/* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */
|
||||
ubfx x10, x10, #0x18, 3
|
||||
|
||||
bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv
|
||||
/* int level = levels_of_unification */
|
||||
|
||||
bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv
|
||||
/* while (level <= levels_of_coherency) { */
|
||||
cmp w9, w10
|
||||
b.hi 1f
|
||||
|
||||
/* Invalidate the entire TLB, and ensure instruction consistency. */
|
||||
tlbi vmalle1is
|
||||
0:
|
||||
/* FlushEntireDataCacheImplWithoutStack(level); */
|
||||
mov w0, w9
|
||||
bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv
|
||||
|
||||
/* level++; */
|
||||
cmp w9, w10
|
||||
add w9, w9, #1
|
||||
|
||||
/* } */
|
||||
b.cc 0b
|
||||
|
||||
/* cpu::DataSynchronizationBarrier(); */
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
mov x30, x23
|
||||
1:
|
||||
mov x30, x24
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheImplWithoutStack() */
|
||||
|
||||
@@ -354,12 +354,21 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv:
|
||||
mrs x17, ttbr0_el1
|
||||
and x17, x17, #(0xFFFF << 48)
|
||||
|
||||
/* Invalidate the address held by FAR (and assume it is valid). */
|
||||
/* Check if FAR is valid by examining the FnV bit. */
|
||||
tbnz x16, #10, 8f
|
||||
|
||||
/* FAR is valid, so we can invalidate the address it holds. */
|
||||
mrs x16, far_el1
|
||||
lsr x16, x16, #12
|
||||
orr x17, x16, x17
|
||||
tlbi vae1, x17
|
||||
b 9f
|
||||
|
||||
8: /* There's a TLB conflict and FAR isn't valid. */
|
||||
/* Invalidate the entire TLB. */
|
||||
tlbi aside1, x17
|
||||
|
||||
9: /* Return from a TLB conflict. */
|
||||
/* Ensure instruction consistency. */
|
||||
dsb ish
|
||||
isb
|
||||
@@ -476,16 +485,33 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv:
|
||||
b 3b
|
||||
|
||||
4: /* Check if there's a TLB conflict that caused the abort. */
|
||||
/* NOTE: There is a Nintendo bug in this code that we correct. */
|
||||
/* Nintendo compares the low 6 bits of x0 without restoring the value. */
|
||||
/* They intend to check the DFSC/IFSC bits of esr_el1, but because they */
|
||||
/* shifted esr earlier, the check is invalid and always fails. */
|
||||
mrs x0, esr_el1
|
||||
and x0, x0, #0x3F
|
||||
cmp x0, #0x30
|
||||
b.ne 1b
|
||||
|
||||
/* Invalidate the address held by FAR (and assume it is valid). */
|
||||
/* Check if FAR is valid by examining the FnV bit. */
|
||||
/* NOTE: Nintendo again has a bug here, the same as above. */
|
||||
/* They do not refresh the value of x0, and again compare with */
|
||||
/* the relevant bit already masked out of x0. */
|
||||
mrs x0, esr_el1
|
||||
tbnz x0, #10, 5f
|
||||
|
||||
/* FAR is valid, so we can invalidate the address it holds. */
|
||||
mrs x0, far_el1
|
||||
lsr x0, x0, #12
|
||||
tlbi vaae1, x0
|
||||
b 6f
|
||||
|
||||
5: /* There's a TLB conflict and FAR isn't valid. */
|
||||
/* Invalidate the entire TLB. */
|
||||
tlbi vmalle1
|
||||
|
||||
6: /* Return from a TLB conflict. */
|
||||
/* Ensure instruction consistency. */
|
||||
dsb ish
|
||||
isb
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ams {
|
||||
namespace {
|
||||
|
||||
/* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */
|
||||
constexpr size_t MallocBufferSize = 12_MB;
|
||||
constexpr size_t MallocBufferSize = 32_MB;
|
||||
alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "../amsmitm_fs_utils.hpp"
|
||||
#include "fsmitm_romfs.hpp"
|
||||
#include "fsmitm_layered_romfs_storage.hpp"
|
||||
#include "memlet/memlet.h"
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
@@ -27,8 +26,6 @@ namespace ams::mitm::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB;
|
||||
|
||||
struct ApplicationWithDynamicHeapInfo {
|
||||
ncm::ProgramId program_id;
|
||||
size_t dynamic_app_heap_size;
|
||||
@@ -44,7 +41,7 @@ namespace ams::mitm::fs {
|
||||
/* Fire Emblem: Engage. */
|
||||
/* Requirement ~32+ MB. */
|
||||
/* No particular heap sensitivity. */
|
||||
{ 0x0100A6301214E000, 20_MB, 0_MB },
|
||||
{ 0x0100A6301214E000, 16_MB, 0_MB },
|
||||
|
||||
/* The Legend of Zelda: Tears of the Kingdom. */
|
||||
/* Requirement ~48 MB. */
|
||||
@@ -88,12 +85,10 @@ namespace ams::mitm::fs {
|
||||
/* NOTE: Lock not necessary, because this is the only location which do 0 -> non-zero. */
|
||||
|
||||
R_ABORT_UNLESS(MapImpl(std::addressof(this->heap_address), this->heap_size));
|
||||
AMS_ABORT_UNLESS(this->heap_address != 0 || this->heap_size == 0);
|
||||
AMS_ABORT_UNLESS(this->heap_address != 0);
|
||||
|
||||
/* Create heap. */
|
||||
if (this->heap_size > 0) {
|
||||
util::ConstructAt(this->heap, reinterpret_cast<void *>(this->heap_address), this->heap_size);
|
||||
}
|
||||
util::ConstructAt(this->heap, reinterpret_cast<void *>(this->heap_address), this->heap_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,52 +156,6 @@ namespace ams::mitm::fs {
|
||||
R_RETURN(os::SetMemoryHeapSize(0));
|
||||
}
|
||||
|
||||
constinit os::SharedMemoryType g_applet_shared_memory;
|
||||
|
||||
Result MapAppletMemory(uintptr_t *out, size_t &size) {
|
||||
/* Ensure that we can try to get a native handle for the shared memory. */
|
||||
AMS_FUNCTION_LOCAL_STATIC_CONSTINIT(bool, s_initialized_memlet, false);
|
||||
if (AMS_UNLIKELY(!s_initialized_memlet)) {
|
||||
R_ABORT_UNLESS(::memletInitialize());
|
||||
s_initialized_memlet = true;
|
||||
}
|
||||
|
||||
/* Try to get a shared handle for the memory. */
|
||||
::Handle shmem_handle = INVALID_HANDLE;
|
||||
u64 shmem_size = 0;
|
||||
if (R_FAILED(::memletCreateAppletSharedMemory(std::addressof(shmem_handle), std::addressof(shmem_size), size))) {
|
||||
/* If we fail, set the heap size to 0. */
|
||||
size = 0;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Set the output size. */
|
||||
size = shmem_size;
|
||||
|
||||
/* Setup the shared memory. */
|
||||
os::AttachSharedMemory(std::addressof(g_applet_shared_memory), shmem_size, shmem_handle, true);
|
||||
|
||||
/* Map the shared memory. */
|
||||
void *mem = os::MapSharedMemory(std::addressof(g_applet_shared_memory), os::MemoryPermission_ReadWrite);
|
||||
AMS_ABORT_UNLESS(mem != nullptr);
|
||||
|
||||
/* Set the output. */
|
||||
*out = reinterpret_cast<uintptr_t>(mem);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result UnmapAppletMemory(uintptr_t, size_t) {
|
||||
/* Check that it's possible for us to unmap. */
|
||||
AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) != os::InvalidNativeHandle);
|
||||
|
||||
/* Unmap. */
|
||||
os::DestroySharedMemory(std::addressof(g_applet_shared_memory));
|
||||
|
||||
/* Check that we unmapped successfully. */
|
||||
AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) == os::InvalidNativeHandle);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Dynamic allocation globals. */
|
||||
constinit os::SdkMutex g_romfs_build_lock;
|
||||
constinit ncm::ProgramId g_dynamic_heap_program_id{};
|
||||
@@ -215,7 +164,6 @@ namespace ams::mitm::fs {
|
||||
|
||||
constinit DynamicHeap<os::AllocateUnsafeMemory, os::FreeUnsafeMemory> g_dynamic_app_heap;
|
||||
constinit DynamicHeap<MapByHeap, UnmapByHeap> g_dynamic_sys_heap;
|
||||
constinit DynamicHeap<MapAppletMemory, UnmapAppletMemory> g_dynamic_let_heap;
|
||||
|
||||
void InitializeDynamicHeapForBuildRomfs(ncm::ProgramId program_id) {
|
||||
if (program_id == g_dynamic_heap_program_id && g_dynamic_app_heap.heap_size > 0) {
|
||||
@@ -227,10 +175,6 @@ namespace ams::mitm::fs {
|
||||
if (g_dynamic_sys_heap.heap_size > 0) {
|
||||
g_dynamic_sys_heap.Map();
|
||||
}
|
||||
|
||||
if (g_dynamic_let_heap.heap_size > 0) {
|
||||
g_dynamic_let_heap.Map();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,33 +183,15 @@ namespace ams::mitm::fs {
|
||||
g_building_from_dynamic_heap = false;
|
||||
|
||||
g_dynamic_app_heap.TryRelease();
|
||||
g_dynamic_let_heap.Reset();
|
||||
}
|
||||
|
||||
constexpr bool CanAllocateFromDynamicAppletHeap(AllocationType type) {
|
||||
switch (type) {
|
||||
case AllocationType_FullPath:
|
||||
case AllocationType_SourceInfo:
|
||||
case AllocationType_Memory:
|
||||
case AllocationType_TableCache:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void *AllocateTracked(AllocationType type, size_t size) {
|
||||
if (g_building_from_dynamic_heap) {
|
||||
void *ret = nullptr;
|
||||
if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) {
|
||||
ret = g_dynamic_let_heap.Allocate(size);
|
||||
}
|
||||
AMS_UNUSED(type);
|
||||
|
||||
if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) {
|
||||
ret = g_dynamic_app_heap.Allocate(size);
|
||||
}
|
||||
if (g_building_from_dynamic_heap) {
|
||||
void *ret = g_dynamic_app_heap.Allocate(size);
|
||||
|
||||
if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) {
|
||||
ret = g_dynamic_sys_heap.Allocate(size);
|
||||
@@ -285,11 +211,7 @@ namespace ams::mitm::fs {
|
||||
AMS_UNUSED(type);
|
||||
AMS_UNUSED(size);
|
||||
|
||||
if (g_dynamic_let_heap.TryFree(p)) {
|
||||
if (!g_building_from_dynamic_heap) {
|
||||
g_dynamic_let_heap.TryRelease();
|
||||
}
|
||||
} else if (g_dynamic_app_heap.TryFree(p)) {
|
||||
if (g_dynamic_app_heap.TryFree(p)) {
|
||||
if (!g_building_from_dynamic_heap) {
|
||||
g_dynamic_app_heap.TryRelease();
|
||||
}
|
||||
@@ -1099,7 +1021,6 @@ namespace ams::mitm::fs {
|
||||
g_dynamic_heap_program_id = program_id;
|
||||
g_dynamic_app_heap.heap_size = GetDynamicAppHeapSize(g_dynamic_heap_program_id);
|
||||
g_dynamic_sys_heap.heap_size = GetDynamicSysHeapSize(g_dynamic_heap_program_id);
|
||||
g_dynamic_let_heap.heap_size = MaximumRomfsBuildAppletMemorySize;
|
||||
|
||||
/* Set output. */
|
||||
*out_size = g_dynamic_app_heap.heap_size;
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -25,12 +25,12 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* ScopedCodeMount functionality. */
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, attrs);
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, platform);
|
||||
}
|
||||
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, attrs);
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, platform);
|
||||
}
|
||||
|
||||
ScopedCodeMount::~ScopedCodeMount() {
|
||||
@@ -46,28 +46,28 @@ namespace ams::ldr {
|
||||
}
|
||||
}
|
||||
|
||||
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) {
|
||||
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) {
|
||||
/* Capture override status, if necessary. */
|
||||
this->EnsureOverrideStatus(loc);
|
||||
AMS_ABORT_UNLESS(m_has_status);
|
||||
|
||||
/* Get the content path. */
|
||||
char content_path[fs::EntryNameLengthMax + 1];
|
||||
R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, attrs));
|
||||
R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform));
|
||||
|
||||
/* Get the content attributes. */
|
||||
const auto content_attributes = attrs.content_attributes;
|
||||
const auto content_attributes = GetPlatformContentAttributes(platform);
|
||||
|
||||
/* Mount the atmosphere code file system. */
|
||||
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_id), m_override_status.IsHbl(), m_override_status.IsProgramSpecific()));
|
||||
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific()));
|
||||
m_mounted_ams = true;
|
||||
|
||||
/* Mount the sd or base code file system. */
|
||||
R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_id)));
|
||||
R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id));
|
||||
m_mounted_sd_or_code = true;
|
||||
|
||||
/* Mount the base code file system. */
|
||||
if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id, static_cast<ncm::StorageId>(loc.storage_id)))) {
|
||||
if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id))) {
|
||||
m_mounted_code = true;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Redirection API. */
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) {
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) {
|
||||
/* Check for storage id none. */
|
||||
if (static_cast<ncm::StorageId>(loc.storage_id) == ncm::StorageId::None) {
|
||||
std::memset(out_path, 0, out_size);
|
||||
@@ -92,7 +92,7 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Get the content attributes. */
|
||||
const auto content_attributes = attrs.content_attributes;
|
||||
const auto content_attributes = GetPlatformContentAttributes(platform);
|
||||
AMS_UNUSED(content_attributes);
|
||||
|
||||
lr::Path path;
|
||||
@@ -166,4 +166,12 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform) {
|
||||
switch (platform) {
|
||||
case ncm::ContentMetaPlatform::Nx:
|
||||
return fs::ContentAttributes_None;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace ams::ldr {
|
||||
bool m_mounted_sd_or_code;
|
||||
bool m_mounted_code;
|
||||
public:
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, ncm::ContentMetaPlatform platform);
|
||||
~ScopedCodeMount();
|
||||
|
||||
Result GetResult() const {
|
||||
@@ -59,7 +59,7 @@ namespace ams::ldr {
|
||||
return m_base_code_verification_data;
|
||||
}
|
||||
private:
|
||||
Result Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs);
|
||||
Result Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform);
|
||||
void EnsureOverrideStatus(const ncm::ProgramLocation &loc);
|
||||
};
|
||||
|
||||
@@ -76,8 +76,10 @@ namespace ams::ldr {
|
||||
#define ENCODE_CMPT_PATH(relative) "cmpt:" relative
|
||||
|
||||
/* Redirection API. */
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs);
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform);
|
||||
Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc);
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc);
|
||||
|
||||
fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform);
|
||||
|
||||
}
|
||||
|
||||
@@ -69,11 +69,6 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_19_0_0[] = {
|
||||
{ 0x6E10, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 },
|
||||
};
|
||||
|
||||
constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_20_0_0[] = {
|
||||
{ 0x7010, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 },
|
||||
{ 0x7090, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 },
|
||||
};
|
||||
|
||||
constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = {
|
||||
{ ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 },
|
||||
{ ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 },
|
||||
@@ -87,5 +82,4 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = {
|
||||
{ ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */
|
||||
{ ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */
|
||||
{ ParseModuleId("54BB9BB32C958E02752DC5E4AE8D016BFE1F5418"), util::size(Usb30ForceEnablePatches_19_0_0), Usb30ForceEnablePatches_19_0_0 }, /* 19.0.0 */
|
||||
{ ParseModuleId("40E80E7442C0DFC985315E6F9E8C77229818AC0F"), util::size(Usb30ForceEnablePatches_20_0_0), Usb30ForceEnablePatches_20_0_0 }, /* 20.0.0 */
|
||||
};
|
||||
|
||||
@@ -27,72 +27,72 @@ namespace ams::ldr {
|
||||
|
||||
constinit ArgumentStore g_argument_store;
|
||||
|
||||
bool IsValidProgramAttributes(const ldr::ProgramAttributes &attrs) {
|
||||
/* Check that the attributes are valid; on NX, this means Platform = NX + no content attrs. */
|
||||
if (attrs.platform != ncm::ContentMetaPlatform::Nx) {
|
||||
return false;
|
||||
}
|
||||
if (attrs.content_attributes != fs::ContentAttributes_None) {
|
||||
return false;
|
||||
bool IsValidPlatform(ncm::ContentMetaPlatform platform) {
|
||||
return platform == ncm::ContentMetaPlatform::Nx;
|
||||
}
|
||||
|
||||
Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) {
|
||||
/* Check that the platform is valid. */
|
||||
R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId());
|
||||
|
||||
/* Get the location and override status. */
|
||||
ncm::ProgramLocation loc;
|
||||
cfg::OverrideStatus override_status;
|
||||
R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, platform));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Create the process. */
|
||||
R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform));
|
||||
}
|
||||
|
||||
Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) {
|
||||
/* Check that the platform is valid. */
|
||||
R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId());
|
||||
|
||||
/* Zero output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, platform));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Get the program info. */
|
||||
cfg::OverrideStatus status;
|
||||
R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, platform));
|
||||
|
||||
if (loc.program_id != out->program_id) {
|
||||
/* Redirect the program path. */
|
||||
const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
R_TRY(RedirectProgramPath(path, sizeof(path), new_loc));
|
||||
|
||||
/* Update the arguments, as needed. */
|
||||
if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) {
|
||||
R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
/* If we should, set the output status. */
|
||||
if (out_status != nullptr) {
|
||||
*out_status = status;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs) {
|
||||
/* Check that the program attributes are valid. */
|
||||
R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes());
|
||||
|
||||
/* Get the location and override status. */
|
||||
ncm::ProgramLocation loc;
|
||||
cfg::OverrideStatus override_status;
|
||||
R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, attrs));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Create the process. */
|
||||
R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, attrs));
|
||||
Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) {
|
||||
R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, ncm::ContentMetaPlatform::Nx));
|
||||
}
|
||||
|
||||
Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) {
|
||||
/* Check that the program attributes are valid. */
|
||||
R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes());
|
||||
|
||||
/* Zero output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, attrs));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Get the program info. */
|
||||
cfg::OverrideStatus status;
|
||||
R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, attrs));
|
||||
|
||||
if (loc.program_id != out->program_id) {
|
||||
/* Redirect the program path. */
|
||||
const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
R_TRY(RedirectProgramPath(path, sizeof(path), new_loc));
|
||||
|
||||
/* Update the arguments, as needed. */
|
||||
if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) {
|
||||
R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we should, set the output status. */
|
||||
if (out_status != nullptr) {
|
||||
*out_status = status;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
|
||||
R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, ncm::ContentMetaPlatform::Nx));
|
||||
}
|
||||
|
||||
Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
|
||||
|
||||
@@ -21,16 +21,16 @@ namespace ams::ldr {
|
||||
class LoaderService {
|
||||
public:
|
||||
/* Official commands. */
|
||||
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ProgramAttributes &attrs) {
|
||||
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h) {
|
||||
/* Create a handle to set the output to when done. */
|
||||
os::NativeHandle handle = os::InvalidNativeHandle;
|
||||
ON_SCOPE_EXIT { proc_h.SetValue(handle, true); };
|
||||
|
||||
R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle(), attrs));
|
||||
R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle()));
|
||||
}
|
||||
|
||||
Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) {
|
||||
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc, attrs));
|
||||
Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc) {
|
||||
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc));
|
||||
}
|
||||
|
||||
Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc) {
|
||||
@@ -75,16 +75,16 @@ namespace ams::ldr {
|
||||
return this->HasLaunchedBootProgram(out.GetPointer(), program_id);
|
||||
}
|
||||
|
||||
Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) {
|
||||
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc, attrs));
|
||||
Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc) {
|
||||
R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc));
|
||||
}
|
||||
|
||||
Result AtmospherePinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status) {
|
||||
R_RETURN(this->PinProgram(out_id.GetPointer(), loc, override_status));
|
||||
}
|
||||
private:
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs);
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc);
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
|
||||
Result SetProgramArgument(ncm::ProgramId program_id, const void *argument, size_t size);
|
||||
Result GetProcessModuleInfo(u32 *out_count, ModuleInfo *out, size_t max_out_count, os::ProcessId process_id);
|
||||
|
||||
@@ -664,15 +664,15 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs) {
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) {
|
||||
/* Mount code. */
|
||||
AMS_UNUSED(path);
|
||||
ScopedCodeMount mount(loc, override_status, attrs);
|
||||
ScopedCodeMount mount(loc, override_status, platform);
|
||||
R_TRY(mount.GetResult());
|
||||
|
||||
/* Load meta, possibly from cache. */
|
||||
Meta meta;
|
||||
R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, attrs.platform));
|
||||
R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform));
|
||||
|
||||
/* Validate meta. */
|
||||
R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData()));
|
||||
@@ -720,16 +720,16 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs) {
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform) {
|
||||
Meta meta;
|
||||
|
||||
/* Load Meta. */
|
||||
{
|
||||
AMS_UNUSED(path);
|
||||
|
||||
ScopedCodeMount mount(loc, attrs);
|
||||
ScopedCodeMount mount(loc, platform);
|
||||
R_TRY(mount.GetResult());
|
||||
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), attrs.platform, false));
|
||||
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false));
|
||||
if (out_status != nullptr) {
|
||||
*out_status = mount.GetOverrideStatus();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
namespace ams::ldr {
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs);
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform);
|
||||
|
||||
Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
|
||||
Result UnpinProgram(PinId id);
|
||||
|
||||
@@ -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))
|
||||
@@ -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
|
||||
}]
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user