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