Compare commits

..

No commits in common. "master" and "1.9.1" have entirely different histories.

165 changed files with 858 additions and 1623 deletions

View File

@ -107,7 +107,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp
cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp
cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp
@PATH="$(DEVKITPRO)/tools/bin:$$PATH" 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
cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro
cp troposphere/daybreak/daybreak.nro $(DIST_DIR)/switch/daybreak.nro
@ -117,7 +117,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
cp fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)/fusee.bin
package3: emummc fusee stratosphere mesosphere exosphere troposphere
$(SILENTCMD)$(PYTHON) fusee/build_package3.py $(CURRENT_DIRECTORY) $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BOOT_OUT_DIR) $(ATMOSPHERE_GIT_HASH) $(ATMOSPHERE_MAJOR_VERSION) $(ATMOSPHERE_MINOR_VERSION) $(ATMOSPHERE_MICRO_VERSION) 0 $(ATMOSPHERE_SUPPORTED_HOS_MAJOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MINOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MICRO_VERSION) 0
@python fusee/build_package3.py $(CURRENT_DIRECTORY) $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BOOT_OUT_DIR) $(ATMOSPHERE_GIT_HASH) $(ATMOSPHERE_MAJOR_VERSION) $(ATMOSPHERE_MINOR_VERSION) $(ATMOSPHERE_MICRO_VERSION) 0 $(ATMOSPHERE_SUPPORTED_HOS_MAJOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MINOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MICRO_VERSION) 0
@echo "Built package3!"
emummc:

View File

@ -1,46 +1,4 @@
# Changelog
## 1.10.0
+ Basic support was added for 21.0.0.
+ The console should boot and atmosphère should be fully functional.
+ **Please note**: All homebrew software may need to be re-compiled with the latest libnx (>= 4.10.0), or else it may crash/experience memory corruption.
+ Nintendo broke the userland<->kernel TLS ABI in 21.0.0, by writing to previously reserved space.
+ Homebrew used this reserved space for its TLS slots, which means any homebrew software using TLS slots will experience memory corruption when running under Atmosphere 1.10.0.
+ This doesn't appear to impact everything, but a large portion of tested homebrew crashes (often on exit), and so will need re-compile for the new ABI.
+ For those technically inclined, while TLS slots are rarely used by developers, they're used to implement features like e.g. C++ exceptions under the hood, and so anything using those crashes, etc.
+ To help make this transition easier, hbmenu now shows a warning when selecting homebrew compiled with an older, incompatible ABI version.
+ I apologize for the hassle in general.
+ libnx has been updated so that its reserved space matches Nintendo's now -- this particular issue can never occur again, even if Nintendo touches more reserved space.
+ `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.
+ `erpt` was updated to reflect the latest official behavior.
+ `pgl` was updated to reflect the latest official behavior.
+ `fatal` was updated to reflect the latest official behavior.
+ Support was added for launching another game-which-has-too-many-files with romfs mods.
+ I rely on user reports for adding support/fixing these, and some of these games can be pretty obscure!
+ 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.
+ Although some games may be impossible to fix, I believe I can get almost everything working, so please let me try to help you (and improve atmosphère's support!) if you run into this!
+ General system stability improvements to enhance the user's experience.
## 1.9.5
+ Basic support was added for 20.5.0.
+ General system stability improvements to enhance the user's experience.
## 1.9.4
+ Basic support was added for 20.4.0.
+ An issue was fixed in `exosphère`'s register accessilibity tables (thanks @CTCaer).
+ I believe this had no impact on official code, though it would have prevented some homebrew from interacting correctly with the MC0/MC1 registers.
+ An issue was fixed that could cause a deadlock when building multiple romfs images simultaneously (thanks @Ereza).
+ This fixes support for certain mods, e.g. system language translations overriding content for both overlayDisp and qlaunch.
+ General system stability improvements to enhance the user's experience.
## 1.9.3
+ Basic support was added for 20.3.0.
+ Compatibility was fixed for loading mods with KOTOR 2 (star wars).
+ General system stability improvements to enhance the user's experience.
## 1.9.2
+ Basic support was added for 20.2.0.
+ USB 3.0 support force-enable was fixed for 20.1.0+.
+ General system stability improvements to enhance the user's experience.
## 1.9.1
+ Basic support was added for 20.1.0.
+ General system stability improvements to enhance the user's experience.

4
emummc/.gitrepo vendored
View File

@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emummc
branch = develop
commit = 3c57b20ba3820ec87d7dd239d6fcf9ba97510606
parent = d61ee942d9b34cadd80464d5d549c5e2e5bf1689
commit = a8e5f1a184aeb8ba884166a1e4f386088d4a6cf1
parent = 409c3cf9e190dbb65fe76570954939cbe8a5eca0
method = merge
cmdver = 0.4.1

2
emummc/README.md vendored
View File

@ -2,7 +2,7 @@
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions
**1.0.0 - 21.0.0**
**1.0.0 - 20.1.0**
## Features
* Arbitrary SDMMC backend selection

View File

@ -79,8 +79,6 @@
#include "offsets/2000_exfat.h"
#include "offsets/2010.h"
#include "offsets/2010_exfat.h"
#include "offsets/2100.h"
#include "offsets/2100_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@ -171,8 +169,6 @@ DEFINE_OFFSET_STRUCT(_2000);
DEFINE_OFFSET_STRUCT(_2000_EXFAT);
DEFINE_OFFSET_STRUCT(_2010);
DEFINE_OFFSET_STRUCT(_2010_EXFAT);
DEFINE_OFFSET_STRUCT(_2100);
DEFINE_OFFSET_STRUCT(_2100_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@ -302,10 +298,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_2010));
case FS_VER_20_1_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT));
case FS_VER_21_0_0:
return &(GET_OFFSET_STRUCT_NAME(_2100));
case FS_VER_21_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2100_EXFAT));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@ -116,9 +116,6 @@ enum FS_VER
FS_VER_20_1_0,
FS_VER_20_1_0_EXFAT,
FS_VER_21_0_0,
FS_VER_21_0_0_EXFAT,
FS_VER_MAX,
};

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_2100_H__
#define __FS_2100_H__
// Accessor vtable getters
#define FS_OFFSET_2100_SDMMC_ACCESSOR_GC 0x1AC970
#define FS_OFFSET_2100_SDMMC_ACCESSOR_SD 0x1AE980
#define FS_OFFSET_2100_SDMMC_ACCESSOR_NAND 0x1ACFA0
// Hooks
#define FS_OFFSET_2100_SDMMC_WRAPPER_READ 0x1A8850
#define FS_OFFSET_2100_SDMMC_WRAPPER_WRITE 0x1A88B0
#define FS_OFFSET_2100_RTLD 0x2E1C0
#define FS_OFFSET_2100_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2100_CLKRST_SET_MIN_V_CLK_RATE 0x1CB9B0
// Misc funcs
#define FS_OFFSET_2100_LOCK_MUTEX 0x1A17D0
#define FS_OFFSET_2100_UNLOCK_MUTEX 0x1A1830
#define FS_OFFSET_2100_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A8810
#define FS_OFFSET_2100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A8830
// Misc Data
#define FS_OFFSET_2100_SD_MUTEX 0xFEE408
#define FS_OFFSET_2100_NAND_MUTEX 0xFE9CF0
#define FS_OFFSET_2100_ACTIVE_PARTITION 0xFE9D30
#define FS_OFFSET_2100_SDMMC_DAS_HANDLE 0xFCBB18
// NOPs
#define FS_OFFSET_2100_SD_DAS_INIT 0x2B5C8
// Nintendo Paths
#define FS_OFFSET_2100_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000718CC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x000824F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008AF18, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A0B8C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2100_H__

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_2100_EXFAT_EXFAT_H__
#define __FS_2100_EXFAT_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_2100_EXFAT_SDMMC_ACCESSOR_GC 0x1B7AD0
#define FS_OFFSET_2100_EXFAT_SDMMC_ACCESSOR_SD 0x1B9AE0
#define FS_OFFSET_2100_EXFAT_SDMMC_ACCESSOR_NAND 0x1B8100
// Hooks
#define FS_OFFSET_2100_EXFAT_SDMMC_WRAPPER_READ 0x1B39B0
#define FS_OFFSET_2100_EXFAT_SDMMC_WRAPPER_WRITE 0x1B3A10
#define FS_OFFSET_2100_EXFAT_RTLD 0x2E1C0
#define FS_OFFSET_2100_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2100_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D6B10
// Misc funcs
#define FS_OFFSET_2100_EXFAT_LOCK_MUTEX 0x1AC930
#define FS_OFFSET_2100_EXFAT_UNLOCK_MUTEX 0x1AC990
#define FS_OFFSET_2100_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B3970
#define FS_OFFSET_2100_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1B3990
// Misc Data
#define FS_OFFSET_2100_EXFAT_SD_MUTEX 0xFFF408
#define FS_OFFSET_2100_EXFAT_NAND_MUTEX 0xFFACF0
#define FS_OFFSET_2100_EXFAT_ACTIVE_PARTITION 0xFFAD30
#define FS_OFFSET_2100_EXFAT_SDMMC_DAS_HANDLE 0xFD8B18
// NOPs
#define FS_OFFSET_2100_EXFAT_SD_DAS_INIT 0x2B5C8
// Nintendo Paths
#define FS_OFFSET_2100_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000718CC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x000824F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008AF18, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A0B8C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2100_EXFAT_EXFAT_H__

View File

@ -70,6 +70,6 @@ clean:
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean ATMOSPHERE_CPU="$(strip $(ATMOSPHERE_BOOT_CPU))"
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
.PHONY: all clean check_lib check_boot_lib check_loader_stub check_program check_mariko_fatal check_warmboot

View File

@ -119,7 +119,7 @@ DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
$(OUTPUT).lz4 : $(OUTPUT).bin
$(SILENTCMD)$(PYTHON) $(CURRENT_DIRECTORY)/split_program.py $(OUTPUT).bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
@python $(CURRENT_DIRECTORY)/split_program.py $(OUTPUT).bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
@echo built ... $(notdir $@)
$(OUTPUT).bin : $(OUTPUT).elf

View File

@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
/* TODO: Update on next change of keys. */
/* Mariko Development Master Kek Source. */
.byte 0x11, 0x1C, 0x13, 0x90, 0xD9, 0x5E, 0xB0, 0xA2, 0xE3, 0xD0, 0x0E, 0x5D, 0xC4, 0xFB, 0x9E, 0xDB
.byte 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
/* Mariko Production Master Kek Source. */
.byte 0xEB, 0xF3, 0x5B, 0x2D, 0x4A, 0x2D, 0xCE, 0x45, 0x3A, 0x6F, 0x61, 0x38, 0x0B, 0x00, 0x3B, 0x46
.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
/* 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. */
@ -111,7 +111,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */
.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */
.byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */
.byte 0x74, 0xB2, 0x5F, 0xA0, 0x4B, 0x74, 0x6D, 0x47, 0x5B, 0xA9, 0xF5, 0x26, 0x46, 0xD7, 0x4B, 0x6E /* Master key 13 encrypted with Master key 14. */
/* 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. */
@ -134,7 +133,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */
.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */
.byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */
.byte 0xF7, 0x92, 0xC0, 0xEC, 0xF3, 0xA4, 0x8C, 0xB7, 0x0D, 0xB3, 0xF3, 0xAB, 0x10, 0x9B, 0x18, 0xBA /* Master key 13 encrypted with Master key 14. */
/* 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. */
@ -154,7 +152,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */
.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */
.byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */
.byte 0xF9, 0x62, 0x05, 0x99, 0xE0, 0xB9, 0xA6, 0x9B, 0x9D, 0xAA, 0xB4, 0x12, 0x0B, 0x0F, 0xF5, 0x8F /* 21.0.0 Device Master Key Source Source. */
/* Development Device Master Kek Sources. */
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
@ -174,7 +171,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */
.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */
.byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */
.byte 0x7A, 0x4C, 0x38, 0xB7, 0x03, 0x6B, 0x1E, 0x81, 0x20, 0x53, 0x14, 0x99, 0xA4, 0x21, 0x92, 0x9F /* 21.0.0 Device Master Kek Source. */
/* Production Device Master Kek Sources. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
@ -194,4 +190,3 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
.byte 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 /* 21.0.0 Device Master Kek Source. */

View File

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

View File

@ -103,8 +103,8 @@ namespace ams::secmon::smc {
constexpr const AccessTableEntry AccessTables[] = {
{ PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
{ McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
};
constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) {

View File

@ -43,6 +43,6 @@ clean:
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/loader_stub -f $(CURRENT_DIRECTORY)/loader_stub/loader_stub.mk clean
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/program -f $(CURRENT_DIRECTORY)/program/program.mk clean
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
.PHONY: all clean check_lib check_loader_stub check_program

View File

@ -84,7 +84,7 @@ DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
$(OUTPUT).lz4 : $(OUTPUT).bin
$(SILENTCMD)$(PYTHON) $(CURRENT_DIRECTORY)/lz4_compress.py $(OUTPUT).bin $(OUTPUT).lz4
@python $(CURRENT_DIRECTORY)/lz4_compress.py $(OUTPUT).bin $(OUTPUT).lz4
@echo built ... $(notdir $@)
$(OUTPUT).bin : $(OUTPUT).elf

View File

@ -23,17 +23,17 @@ namespace ams::nxboot {
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */
0xEB, 0xF3, 0x5B, 0x2D, 0x4A, 0x2D, 0xCE, 0x45, 0x3A, 0x6F, 0x61, 0x38, 0x0B, 0x00, 0x3B, 0x46
0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
};
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */
0x11, 0x1C, 0x13, 0x90, 0xD9, 0x5E, 0xB0, 0xA2, 0xE3, 0xD0, 0x0E, 0x5D, 0xC4, 0xFB, 0x9E, 0xDB
0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
};
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
/* TODO: Update on next change of keys. */
0x66, 0xC8, 0xCB, 0x3D, 0xEC, 0xF4, 0x59, 0x73, 0x54, 0x88, 0xE1, 0x2E, 0xE6, 0x3D, 0x68, 0x46
0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8
};
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
@ -74,7 +74,6 @@ namespace ams::nxboot {
{ 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */
{ 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */
{ 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */
{ 0xF9, 0x62, 0x05, 0x99, 0xE0, 0xB9, 0xA6, 0x9B, 0x9D, 0xAA, 0xB4, 0x12, 0x0B, 0x0F, 0xF5, 0x8F }, /* 21.0.0 Device Master Key Source Source. */
};
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
@ -95,7 +94,6 @@ namespace ams::nxboot {
{ 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */
{ 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */
{ 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */
{ 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 }, /* 21.0.0 Device Master Kek Source. */
};
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
@ -116,7 +114,6 @@ namespace ams::nxboot {
{ 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */
{ 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */
{ 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */
{ 0x7A, 0x4C, 0x38, 0xB7, 0x03, 0x6B, 0x1E, 0x81, 0x20, 0x53, 0x14, 0x99, 0xA4, 0x21, 0x92, 0x9F }, /* 21.0.0 Device Master Kek Source. */
};
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
@ -140,7 +137,6 @@ namespace ams::nxboot {
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */
{ 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */
{ 0xF7, 0x92, 0xC0, 0xEC, 0xF3, 0xA4, 0x8C, 0xB7, 0x0D, 0xB3, 0xF3, 0xAB, 0x10, 0x9B, 0x18, 0xBA }, /* Master key 13 encrypted with Master key 14. */
};
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
@ -164,7 +160,6 @@ namespace ams::nxboot {
{ 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */
{ 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */
{ 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */
{ 0x74, 0xB2, 0x5F, 0xA0, 0x4B, 0x74, 0x6D, 0x47, 0x5B, 0xA9, 0xF5, 0x26, 0x46, 0xD7, 0x4B, 0x6E }, /* Master key 13 encrypted with Master key 14. */
};
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};

View File

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

View File

@ -265,8 +265,6 @@ namespace ams::nxboot {
return ams::TargetFirmware_19_0_0;
} else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) {
return ams::TargetFirmware_20_0_0;
} else if (std::memcmp(package1 + 0x10, "20251009", 8) == 0) {
return ams::TargetFirmware_21_0_0;
}
break;
default:
@ -411,9 +409,8 @@ namespace ams::nxboot {
/* If we should, save the current warmboot firmware. */
UpdateWarmbootPath(expected_fuses);
if (!IsFileExist(warmboot_path)) {
/* Try to create the directory/file, allowing them to fail (if already exist). */
static_cast<void>(fs::CreateDirectory("sdmc:/warmboot_mariko"));
static_cast<void>(fs::CreateFile(warmboot_path, warmboot_src_size));
fs::CreateDirectory("sdmc:/warmboot_mariko");
fs::CreateFile(warmboot_path, warmboot_src_size);
Result result;
fs::FileHandle file;

View File

@ -186,9 +186,6 @@ namespace ams::nxboot {
FsVersion_20_1_0,
FsVersion_20_1_0_Exfat,
FsVersion_21_0_0,
FsVersion_21_0_0_Exfat,
FsVersion_Count,
};
@ -287,9 +284,6 @@ namespace ams::nxboot {
{ 0xED, 0x34, 0xB4, 0x50, 0x58, 0x4A, 0x5B, 0x43 }, /* FsVersion_20_1_0 */
{ 0xA5, 0x1A, 0xA4, 0x92, 0x6C, 0x41, 0x87, 0x59 }, /* FsVersion_20_1_0_Exfat */
{ 0xEE, 0x4B, 0x30, 0x12, 0xA6, 0x84, 0x02, 0x25 }, /* FsVersion_21_0_0 */
{ 0x6E, 0x2B, 0xD9, 0xBA, 0xA3, 0xB9, 0x10, 0xF1 }, /* FsVersion_21_0_0_Exfat */
};
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
@ -691,16 +685,6 @@ namespace ams::nxboot {
AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1));
break;
case FsVersion_21_0_0:
AddPatch(fs_meta, 0x1AC9ED, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1ACA05 , NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x17FBE0, NogcPatch1, sizeof(NogcPatch1));
break;
case FsVersion_21_0_0_Exfat:
AddPatch(fs_meta, 0x1B7B4D, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1B7B65, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x18AD40, NogcPatch1, sizeof(NogcPatch1));
break;
default:
break;
}

View File

@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 6cc765fcaa5f83b9cd6dc5b424bae31a0f33b29f
parent = 3cb5d5f957020d07f5bdb3fb89521f29bea5d79d
commit = 0f72b2ceba36c4255763d79ec48575ceb41d2539
parent = 77603bf7e54cc2717ec38c0c3fc98621c78ff642
method = merge
cmdver = 0.4.1

View File

@ -297,23 +297,6 @@ FIND_SOURCE_FILES=$(foreach dir,$1,$(filter-out $(notdir $(wildcard $(dir)/*.arc
ATMOSPHERE_GCH_IDENTIFIER := $(ATMOSPHERE_FULL_NAME)
#---------------------------------------------------------------------------------
# Python. The scripts should work with Python 2 or 3, but 2 is preferred.
#---------------------------------------------------------------------------------
PYTHON = $(shell command -v python >/dev/null && echo python || echo python3)
#---------------------------------------------------------------------------------
# Export MAKE:
# GCC's LTO driver invokes Make internally. This invocation respects both $(MAKE)
# and $(MAKEFLAGS), but only if they're in the environment. By default, MAKEFLAGS
# is in the environment while MAKE isn't, so GCC will always use the default
# `make` command, yet it inherits MAKEFLAGS from the copy of Make the user
# invoked, which might have incompatible flags. In practice this is an issue on
# macOS when running e.g. `gmake -j32 -Otarget`. This behavior is arguably a bug
# in GCC and/or Make, but we can work around it by exporting MAKE.
#---------------------------------------------------------------------------------
export MAKE
#---------------------------------------------------------------------------------
# Rules for compiling pre-compiled headers
#---------------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
endif
export DEFINES = $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -Wno-error=unused-result
export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers
export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)

View File

@ -40,7 +40,6 @@ namespace ams::pkg1 {
KeyGeneration_18_0_0 = 0x11,
KeyGeneration_19_0_0 = 0x12,
KeyGeneration_20_0_0 = 0x13,
KeyGeneration_21_0_0 = 0x14,
KeyGeneration_Count,

View File

@ -24,7 +24,7 @@ namespace ams::pkg2 {
constexpr inline int PayloadCount = 3;
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */
constexpr inline int CurrentBootloaderVersion = 0x18;
constexpr inline int CurrentBootloaderVersion = 0x17;
struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>;

View File

@ -104,7 +104,7 @@ clean:
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@

View File

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

View File

@ -83,9 +83,9 @@ namespace ams::kern::arch::arm64 {
}
NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
NOINLINE void UnbindHandler(s32 irq, s32 core);
NOINLINE Result UnbindHandler(s32 irq, s32 core);
NOINLINE void ClearInterrupt(s32 irq, s32 core_id);
NOINLINE Result ClearInterrupt(s32 irq, s32 core_id);
ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
m_interrupt_controller.SendInterProcessorInterrupt(irq, core_mask);
@ -99,10 +99,10 @@ namespace ams::kern::arch::arm64 {
private:
Result BindGlobal(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
Result BindLocal(KInterruptHandler *handler, s32 irq, s32 priority, bool manual_clear);
void UnbindGlobal(s32 irq);
void UnbindLocal(s32 irq);
void ClearGlobal(s32 irq);
void ClearLocal(s32 irq);
Result UnbindGlobal(s32 irq);
Result UnbindLocal(s32 irq);
Result ClearGlobal(s32 irq);
Result ClearLocal(s32 irq);
private:
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() {
u64 intr_state;

View File

@ -197,9 +197,9 @@ namespace ams::kern::arch::arm64 {
cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id);
}
NOINLINE void 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);
void Finalize();
Result Finalize();
static void NoteUpdatedCallback(const void *pt) {
/* Note the update. */

View File

@ -165,7 +165,7 @@ namespace ams::kern::arch::arm64 {
constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_fpcr(), m_fpsr(), m_callee_saved_fpu(), m_locked() { /* ... */ }
explicit KThreadContext() { /* ... */ }
void Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main);
Result Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main);
void SetArguments(uintptr_t arg0, uintptr_t arg1);

View File

@ -35,7 +35,7 @@ namespace ams::kern::arch::arm64 {
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, u32 value);
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);
@ -100,8 +100,8 @@ namespace ams::kern::arch::arm64 {
return Impl::CopyMemoryToUserAligned64Bit(dst, src, size);
}
static bool CopyMemoryToUserSize32Bit(void *dst, u32 value) {
return Impl::CopyMemoryToUserSize32Bit(dst, value);
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src) {
return Impl::CopyMemoryToUserSize32Bit(dst, src);
}
static s32 CopyStringToUser(void *dst, const void *src, size_t size) {

View File

@ -47,6 +47,13 @@
/* re-enabled by toggling this define. */
//#define MESOSPHERE_ENABLE_PROCESS_CREATION_TIME
/* NOTE: This enables fast class token storage using a class member. */
/* This saves a virtual call when doing KAutoObject->DynCast<>(), */
/* at the cost of storing class tokens inside the class object. */
/* However, as of (10/16/2021) KAutoObject has an unused class member */
/* of the right side, and so this does not actually cost any space. */
#define MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST
/* NOTE: This enables usage of KDebug handles as parameter for svc::GetInfo */
/* calls which require a process parameter. This enables a debugger to obtain */
/* address space/layout information, for example. However, it changes abi, and so */

View File

@ -121,9 +121,14 @@ namespace ams::kern {
private:
KAutoObject *m_next_closed_object;
ReferenceCount m_ref_count;
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
ClassTokenType m_class_token;
#endif
public:
constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0), m_class_token(0)
constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0)
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
, m_class_token(0)
#endif
{
MESOSPHERE_ASSERT_THIS();
}
@ -146,11 +151,19 @@ namespace ams::kern {
}
ALWAYS_INLINE bool IsDerivedFrom(const TypeObj &rhs) const {
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.GetClassToken());
#else
return this->GetTypeObj().IsDerivedFrom(rhs);
#endif
}
ALWAYS_INLINE bool IsDerivedFrom(const KAutoObject &rhs) const {
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.m_class_token);
#else
return this->IsDerivedFrom(rhs.GetTypeObj());
#endif
}
template<typename Derived>
@ -205,10 +218,12 @@ namespace ams::kern {
KAutoObject &auto_object = *static_cast<KAutoObject *>(obj);
/* If we should, set our class token. */
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
{
constexpr auto Token = Derived::GetStaticTypeObj().GetClassToken();
auto_object.m_class_token = Token;
}
#endif
/* Initialize reference count to 1. */
auto_object.m_ref_count = 1;

View File

@ -93,9 +93,9 @@ namespace ams::kern {
static Result ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
public:
static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
static void OnExitProcess(KProcess *process);
static void OnTerminateProcess(KProcess *process);
static void OnExitThread(KThread *thread);
static Result OnExitProcess(KProcess *process);
static Result OnTerminateProcess(KProcess *process);
static Result OnExitThread(KThread *thread);
static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, u64 thread_id, const uintptr_t *params, size_t num_params);
};

View File

@ -50,8 +50,8 @@ namespace ams::kern {
KReadableEvent &GetReadableEvent() { return m_readable_event; }
void Signal();
void Clear();
Result Signal();
Result Clear();
ALWAYS_INLINE void OnReadableEventDestroyed() { m_readable_event_destroyed = true; }
};

View File

@ -105,7 +105,7 @@ namespace ams::kern {
constexpr ALWAYS_INLINE size_t GetCount() const { return m_count; }
constexpr ALWAYS_INLINE size_t GetMaxCount() const { return m_max_count; }
MESOSPHERE_NOINLINE_IF_DEBUG void Finalize();
MESOSPHERE_NOINLINE_IF_DEBUG Result Finalize();
MESOSPHERE_NOINLINE_IF_DEBUG bool Remove(ams::svc::Handle handle);
template<typename T = KAutoObject>

View File

@ -38,11 +38,13 @@ namespace ams::kern {
Result Reset();
void Clear() {
Result Clear() {
MESOSPHERE_ASSERT_THIS();
/* Try to perform a reset, ignoring whether it succeeds. */
static_cast<void>(this->Reset());
/* Try to perform a reset, succeeding unconditionally. */
this->Reset();
R_SUCCEED();
}
bool IsInitialized() const { return m_is_initialized; }

View File

@ -226,7 +226,7 @@ namespace ams::kern {
explicit KPageTableBase() { /* ... */ }
NOINLINE void InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit);
void Finalize();

View File

@ -269,7 +269,7 @@ namespace ams::kern {
void RemoveIoRegion(KIoRegion *io_region);
Result CreateThreadLocalRegion(KProcessAddress *out);
void DeleteThreadLocalRegion(KProcessAddress addr);
Result DeleteThreadLocalRegion(KProcessAddress addr);
void *GetThreadLocalRegionPointer(KProcessAddress addr);
constexpr KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; }

View File

@ -35,14 +35,16 @@ namespace ams::kern {
constexpr KEvent *GetParent() const { return m_parent; }
void Signal();
Result Signal();
Result Reset();
void Clear() {
Result Clear() {
MESOSPHERE_ASSERT_THIS();
/* Try to perform a reset, ignoring whether it succeeds. */
static_cast<void>(this->Reset());
/* Try to perform a reset, succeeding unconditionally. */
this->Reset();
R_SUCCEED();
}
virtual bool IsSignaled() const override;

View File

@ -105,7 +105,7 @@ namespace ams::kern {
util::Atomic<u8> dpc_flags;
u8 current_svc_id;
u8 reserved_2c;
util::Atomic<u8> exception_flags;
u8 exception_flags;
bool is_pinned;
u8 reserved_2f;
u8 reserved_30[0x10];
@ -417,17 +417,17 @@ namespace ams::kern {
private:
ALWAYS_INLINE void SetExceptionFlag(ExceptionFlag flag) {
MESOSPHERE_ASSERT_THIS();
this->GetStackParameters().exception_flags.FetchOr<std::memory_order_relaxed>(flag);
this->GetStackParameters().exception_flags |= flag;
}
ALWAYS_INLINE void ClearExceptionFlag(ExceptionFlag flag) {
MESOSPHERE_ASSERT_THIS();
this->GetStackParameters().exception_flags.FetchAnd<std::memory_order_relaxed>(~flag);
this->GetStackParameters().exception_flags &= ~flag;
}
ALWAYS_INLINE bool IsExceptionFlagSet(ExceptionFlag flag) const {
MESOSPHERE_ASSERT_THIS();
return this->GetStackParameters().exception_flags.Load<std::memory_order_relaxed>() & flag;
return this->GetStackParameters().exception_flags & flag;
}
public:
/* ALWAYS_INLINE void SetCallingSvc() { return this->SetExceptionFlag(ExceptionFlag_IsCallingSvc); } */
@ -523,7 +523,7 @@ namespace ams::kern {
Result GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
void GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
Result GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
constexpr ThreadState GetState() const { return static_cast<ThreadState>(m_thread_state & ThreadState_Mask); }
constexpr ThreadState GetRawState() const { return m_thread_state; }
@ -717,7 +717,7 @@ namespace ams::kern {
}
void SetBasePriority(s32 priority);
void SetPriorityToIdle();
Result SetPriorityToIdle();
Result Run();
void Exit();
@ -725,7 +725,7 @@ namespace ams::kern {
Result Terminate();
ThreadState RequestTerminate();
void Sleep(s64 timeout);
Result Sleep(s64 timeout);
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(m_kernel_stack_top) - 1; }
ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; }

View File

@ -77,7 +77,7 @@ namespace ams::kern {
}
public:
Result Initialize(KProcess *process);
void Finalize();
Result Finalize();
KProcessAddress Reserve();
void Release(KProcessAddress addr);

View File

@ -86,7 +86,7 @@ clean:
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@

View File

@ -215,7 +215,7 @@ namespace ams::kern::arch::arm64::cpu {
KThread::Register(new_thread);
/* Run the thread. */
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
new_thread->Run();
}
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
@ -508,16 +508,16 @@ namespace ams::kern::arch::arm64::cpu {
g_cache_operation_handler.Initialize(core_id);
/* Bind all handlers to the relevant interrupts. */
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_cache_operation_handler), KInterruptName_CacheOperation, core_id, KInterruptController::PriorityLevel_High, false, false));
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_thread_termination_handler), KInterruptName_ThreadTerminate, core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_core_barrier_handler), KInterruptName_CoreBarrier, core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
Kernel::GetInterruptManager().BindHandler(std::addressof(g_cache_operation_handler), KInterruptName_CacheOperation, core_id, KInterruptController::PriorityLevel_High, false, false);
Kernel::GetInterruptManager().BindHandler(std::addressof(g_thread_termination_handler), KInterruptName_ThreadTerminate, core_id, KInterruptController::PriorityLevel_Scheduler, false, false);
Kernel::GetInterruptManager().BindHandler(std::addressof(g_core_barrier_handler), KInterruptName_CoreBarrier, core_id, KInterruptController::PriorityLevel_Scheduler, false, false);
/* If we should, enable user access to the performance counter registers. */
if (KTargetSystem::IsUserPmuAccessEnabled()) { SetPmUserEnrEl0(1ul); }
/* If we should, enable the kernel performance counter interrupt handler. */
#if defined(MESOSPHERE_ENABLE_PERFORMANCE_COUNTER)
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false));
Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false);
#endif
}

View File

@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue()));
/* Bind the interrupt task for this core. */
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true));
Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true);
}
void KHardwareTimer::Finalize() {

View File

@ -126,7 +126,7 @@ namespace ams::kern::arch::arm64 {
if (entry.handler != nullptr) {
/* Set manual clear needed if relevant. */
if (entry.manually_cleared) {
m_interrupt_controller.Disable(irq);
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
entry.needs_clear = true;
}
@ -242,40 +242,40 @@ namespace ams::kern::arch::arm64 {
}
}
void KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
Result KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id);
MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
if (KInterruptController::IsGlobal(irq)) {
KScopedInterruptDisable di;
KScopedSpinLock lk(this->GetGlobalInterruptLock());
return this->UnbindGlobal(irq);
} else if (KInterruptController::IsLocal(irq)) {
R_RETURN(this->UnbindGlobal(irq));
} else {
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
KScopedInterruptDisable di;
return this->UnbindLocal(irq);
R_RETURN(this->UnbindLocal(irq));
}
}
void KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
Result KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id);
MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
if (KInterruptController::IsGlobal(irq)) {
KScopedInterruptDisable di;
KScopedSpinLock lk(this->GetGlobalInterruptLock());
return this->ClearGlobal(irq);
} else if (KInterruptController::IsLocal(irq)) {
R_RETURN(this->ClearGlobal(irq));
} else {
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
KScopedInterruptDisable di;
return this->ClearLocal(irq);
R_RETURN(this->ClearLocal(irq));
}
}
@ -332,7 +332,7 @@ namespace ams::kern::arch::arm64 {
R_SUCCEED();
}
void KInterruptManager::UnbindGlobal(s32 irq) {
Result KInterruptManager::UnbindGlobal(s32 irq) {
for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) {
m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
}
@ -340,35 +340,50 @@ namespace ams::kern::arch::arm64 {
m_interrupt_controller.Disable(irq);
GetGlobalInterruptEntry(irq).handler = nullptr;
R_SUCCEED();
}
void KInterruptManager::UnbindLocal(s32 irq) {
Result KInterruptManager::UnbindLocal(s32 irq) {
auto &entry = this->GetLocalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
m_interrupt_controller.Disable(irq);
this->GetLocalInterruptEntry(irq).handler = nullptr;
entry.handler = nullptr;
R_SUCCEED();
}
void KInterruptManager::ClearGlobal(s32 irq) {
/* Get the entry. */
Result KInterruptManager::ClearGlobal(s32 irq) {
/* We can't clear an entry with no handler. */
auto &entry = GetGlobalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
/* If not auto-cleared, clear and enable. */
if (entry.manually_cleared && entry.needs_clear) {
/* If auto-cleared, we can succeed immediately. */
R_SUCCEED_IF(!entry.manually_cleared);
R_SUCCEED_IF(!entry.needs_clear);
/* Clear and enable. */
entry.needs_clear = false;
m_interrupt_controller.Enable(irq);
}
R_SUCCEED();
}
void KInterruptManager::ClearLocal(s32 irq) {
/* Get the entry. */
Result KInterruptManager::ClearLocal(s32 irq) {
/* We can't clear an entry with no handler. */
auto &entry = this->GetLocalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
/* If not auto-cleared, clear and enable. */
if (entry.manually_cleared && entry.needs_clear) {
/* If auto-cleared, we can succeed immediately. */
R_SUCCEED_IF(!entry.manually_cleared);
R_SUCCEED_IF(!entry.needs_clear);
/* Clear and set priority. */
entry.needs_clear = false;
m_interrupt_controller.Enable(irq);
}
m_interrupt_controller.SetPriorityLevel(irq, entry.priority);
R_SUCCEED();
}
}

View File

@ -119,13 +119,15 @@ namespace ams::kern::arch::arm64 {
MESOSPHERE_UNUSED(core_id);
}
void KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
Result KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
/* Initialize basic fields. */
m_asid = 0;
m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer();
/* Initialize the base page table. */
KPageTableBase::InitializeForKernel(true, table, start, end);
MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end));
R_SUCCEED();
}
Result KPageTable::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) {
@ -151,7 +153,7 @@ namespace ams::kern::arch::arm64 {
R_SUCCEED();
}
void KPageTable::Finalize() {
Result KPageTable::Finalize() {
/* Only process tables should be finalized. */
MESOSPHERE_ASSERT(!this->IsKernel());
@ -269,6 +271,8 @@ namespace ams::kern::arch::arm64 {
/* Perform inherited finalization. */
KPageTableBase::Finalize();
}
R_SUCCEED();
}
Result KPageTable::OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) {
@ -938,7 +942,7 @@ namespace ams::kern::arch::arm64 {
/* If we should flush entries, do so. */
if ((apply_option & ApplyOption_FlushDataCache) != 0) {
if (IsHeapPhysicalAddress(next_entry.phys_addr)) {
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size));
cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size);
}
}

View File

@ -37,7 +37,7 @@ namespace ams::kern::arch::arm64 {
KScopedInterruptEnable ei;
const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) };
static_cast<void>(KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)));
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params));
}
/* Handle any pending dpc. */
@ -116,7 +116,7 @@ namespace ams::kern::arch::arm64 {
}
void KThreadContext::Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main) {
Result KThreadContext::Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main) {
MESOSPHERE_ASSERT(k_sp != Null<KVirtualAddress>);
/* Ensure that the stack pointers are aligned. */
@ -157,6 +157,8 @@ namespace ams::kern::arch::arm64 {
/* Lock the context, if we're a main thread. */
m_locked = is_main;
R_SUCCEED();
}
void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) {

View File

@ -306,14 +306,15 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
mov x0, #1
ret
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, u32 value) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj, %function
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function
.balign 0x10
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj:
/* Just store a u32. */
sttr w1, [x0]
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
/* Just load and store a u32. */
ldr w2, [x1]
sttr w2, [x0]
/* We're done. */
mov x0, #1

View File

@ -660,7 +660,8 @@ namespace ams::kern::board::nintendo::nx {
ptm.Open(table_virt_addr, 1);
/* Save the page. Note that it is a pre-condition that the page is cleared, when allocated from the system page table manager. */
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize));
/* NOTE: Nintendo does not check the result of StoreDataCache. */
cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize);
g_reserved_table_phys_addr = table_phys_addr;
/* Reserve an asid to correspond to no device. */
@ -709,7 +710,7 @@ namespace ams::kern::board::nintendo::nx {
/* Install interrupt handler. */
#if defined(MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT)
{
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_mc_interrupt_task), KInterruptName_MemoryController, GetCurrentCoreId(), KInterruptController::PriorityLevel_High, true, true));
Kernel::GetInterruptManager().BindHandler(std::addressof(g_mc_interrupt_task), KInterruptName_MemoryController, GetCurrentCoreId(), KInterruptController::PriorityLevel_High, true, true);
}
#endif
}
@ -805,7 +806,7 @@ namespace ams::kern::board::nintendo::nx {
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
ptm.Open(table_vaddr, 1);
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize));
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize);
m_tables[i] = table_vaddr;
}
@ -1041,7 +1042,7 @@ namespace ams::kern::board::nintendo::nx {
if (l2_index == 0 && util::IsAligned(GetInteger(phys_addr), DeviceLargePageSize) && remaining >= DeviceLargePageSize) {
/* Set the large page. */
l1[l1_index].SetLargePage(read, write, true, phys_addr);
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
/* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1061,11 +1062,11 @@ namespace ams::kern::board::nintendo::nx {
const KVirtualAddress table_vaddr = ptm.Allocate();
R_UNLESS(table_vaddr != Null<KVirtualAddress>, svc::ResultOutOfMemory());
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize));
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize);
/* Set the l1 table. */
l1[l1_index].SetTable(true, true, true, GetPageTablePhysicalAddress(table_vaddr));
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
/* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1092,7 +1093,7 @@ namespace ams::kern::board::nintendo::nx {
/* Add a reference to the l2 page (from the l2 entry page). */
ptm.Open(KVirtualAddress(l2), 1);
}
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry));
/* Invalidate the page table cache. */
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
@ -1198,7 +1199,7 @@ namespace ams::kern::board::nintendo::nx {
++num_closed;
}
}
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry));
/* Invalidate the page table cache. */
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
@ -1242,7 +1243,7 @@ namespace ams::kern::board::nintendo::nx {
if (ptm.Close(KVirtualAddress(l2), num_closed)) {
/* Invalidate the l1 entry. */
l1[l1_index].Invalidate();
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
/* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1265,7 +1266,7 @@ namespace ams::kern::board::nintendo::nx {
/* Invalidate the entry. */
l1[l1_index].Invalidate();
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
/* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));

View File

@ -441,7 +441,7 @@ namespace ams::kern::board::nintendo::nx {
KThread::Register(new_thread);
/* Run the thread. */
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
new_thread->Run();
}
}

View File

@ -361,19 +361,11 @@ namespace ams::kern::board::nintendo::nx {
}();
/* Return (possibly) adjusted size. */
/* NOTE: On 20.0.0+ (and even more-so 21.0.0+) the browser requires much more memory in the applet pool in order to function. */
/* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */
/* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */
if (kern::GetTargetFirmware() >= ams::TargetFirmware_21_0_0) {
constexpr size_t ExtraSystemMemoryForAtmosphere_21_0_0 = 7_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere_21_0_0 - KTraceBufferSize;
} else if (kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0) {
constexpr size_t ExtraSystemMemoryForAtmosphere_20_0_0 = 14_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere_20_0_0 - KTraceBufferSize;
} else {
constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB;
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
}
}
size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() {
/* Verify that our minimum is at least as large as Nintendo's. */

View File

@ -140,12 +140,14 @@ namespace ams::kern {
/* Add the previously reserved pages. */
if (src_pool == dst_pool && binary_pages != 0) {
MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages));
/* NOTE: Nintendo does not check the result of this operation. */
pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages);
}
/* Add the previously unreserved pages. */
for (const auto &block : unreserve_pg) {
MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(block.GetAddress(), block.GetNumPages()));
/* NOTE: Nintendo does not check the result of this operation. */
pg.AddBlock(block.GetAddress(), block.GetNumPages());
}
}
MESOSPHERE_ABORT_UNLESS(pg.GetNumPages() == static_cast<size_t>(params.code_num_pages));

View File

@ -37,7 +37,7 @@ namespace ams::kern {
/* Clear and store cache. */
void * const block_address = GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block.GetAddress()));
std::memset(block_address, 0xFF, block.GetSize());
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(block_address, block.GetSize()));
cpu::StoreDataCache(block_address, block.GetSize());
}
/* Set remaining tracking members. */

View File

@ -23,8 +23,8 @@ namespace ams::kern {
return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address));
}
ALWAYS_INLINE bool WriteToUser(KProcessAddress address, u32 val) {
return UserspaceAccess::CopyMemoryToUserSize32Bit(GetVoidPointer(address), val);
ALWAYS_INLINE bool WriteToUser(KProcessAddress address, const u32 *p) {
return UserspaceAccess::CopyMemoryToUserSize32Bit(GetVoidPointer(address), p);
}
ALWAYS_INLINE bool UpdateLockAtomic(u32 *out, KProcessAddress address, u32 if_zero, u32 new_orr_mask) {
@ -94,7 +94,7 @@ namespace ams::kern {
/* Write the value to userspace. */
Result result;
if (AMS_LIKELY(WriteToUser(addr, next_value))) {
if (AMS_LIKELY(WriteToUser(addr, std::addressof(next_value)))) {
result = ResultSuccess();
} else {
result = svc::ResultInvalidCurrentMemory();
@ -210,8 +210,8 @@ namespace ams::kern {
/* If we have no waiters, clear the has waiter flag. */
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
constexpr u32 HasNoWaiterFlag = 0;
WriteToUser(cv_key, HasNoWaiterFlag);
const u32 has_waiter_flag = 0;
WriteToUser(cv_key, std::addressof(has_waiter_flag));
}
}
}
@ -252,13 +252,13 @@ namespace ams::kern {
/* Write to the cv key. */
{
constexpr u32 HasWaiterFlag = 1;
WriteToUser(key, HasWaiterFlag);
const u32 has_waiter_flag = 1;
WriteToUser(key, std::addressof(has_waiter_flag));
cpu::DataMemoryBarrierInnerShareable();
}
/* Write the value to userspace. */
if (!WriteToUser(addr, next_value)) {
if (!WriteToUser(addr, std::addressof(next_value))) {
slp.CancelSleep();
R_THROW(svc::ResultInvalidCurrentMemory());
}

View File

@ -416,8 +416,7 @@ namespace ams::kern {
KProcess * const target = this->GetProcessUnsafe();
/* Terminate the process. */
/* NOTE: This result is seemingly-intentionally not checked by Nintendo. */
static_cast<void>(target->Terminate());
target->Terminate();
R_SUCCEED();
}
@ -1134,7 +1133,7 @@ namespace ams::kern {
R_SUCCEED();
}
void KDebugBase::OnExitProcess(KProcess *process) {
Result KDebugBase::OnExitProcess(KProcess *process) {
MESOSPHERE_ASSERT(process != nullptr);
/* Check if we're attached to a debugger. */
@ -1149,9 +1148,11 @@ namespace ams::kern {
debug->NotifyAvailable();
}
}
R_SUCCEED();
}
void KDebugBase::OnTerminateProcess(KProcess *process) {
Result KDebugBase::OnTerminateProcess(KProcess *process) {
MESOSPHERE_ASSERT(process != nullptr);
/* Check if we're attached to a debugger. */
@ -1166,17 +1167,21 @@ namespace ams::kern {
debug->NotifyAvailable();
}
}
R_SUCCEED();
}
void KDebugBase::OnExitThread(KThread *thread) {
Result KDebugBase::OnExitThread(KThread *thread) {
MESOSPHERE_ASSERT(thread != nullptr);
/* Check if we're attached to a debugger. */
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) {
/* If we are, submit the event. */
const uintptr_t params[2] = { thread->GetId(), static_cast<uintptr_t>(thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread) };
static_cast<void>(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params)));
R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params)));
}
R_SUCCEED();
}
}

View File

@ -167,7 +167,7 @@ namespace ams::kern {
KThread::Register(new_thread);
/* Run the thread. */
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
new_thread->Run();
}
void KDpcManager::HandleDpc() {

View File

@ -38,20 +38,20 @@ namespace ams::kern {
MESOSPHERE_ASSERT_THIS();
}
void KEvent::Signal() {
Result KEvent::Signal() {
KScopedSchedulerLock sl;
if (!m_readable_event_destroyed) {
m_readable_event.Signal();
}
R_SUCCEED_IF(m_readable_event_destroyed);
R_RETURN(m_readable_event.Signal());
}
void KEvent::Clear() {
Result KEvent::Clear() {
KScopedSchedulerLock sl;
if (!m_readable_event_destroyed) {
m_readable_event.Clear();
}
R_SUCCEED_IF(m_readable_event_destroyed);
R_RETURN(m_readable_event.Clear());
}
void KEvent::PostDestroy(uintptr_t arg) {

View File

@ -17,7 +17,7 @@
namespace ams::kern {
void KHandleTable::Finalize() {
Result KHandleTable::Finalize() {
MESOSPHERE_ASSERT_THIS();
/* Get the table and clear our record of it. */
@ -35,6 +35,8 @@ namespace ams::kern {
obj->Close();
}
}
R_SUCCEED();
}
bool KHandleTable::Remove(ams::svc::Handle handle) {

View File

@ -88,7 +88,7 @@ namespace ams::kern {
}
}
void KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
/* Initialize our members. */
m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
m_address_space_start = KProcessAddress(GetInteger(start));
@ -130,7 +130,7 @@ namespace ams::kern {
m_impl.InitializeForKernel(table, start, end);
/* Initialize our memory block manager. */
MESOSPHERE_R_ABORT_UNLESS(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager));
R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager));
}
Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) {
@ -1792,7 +1792,7 @@ namespace ams::kern {
/* Ensure cache coherency, if we're setting pages as executable. */
if (is_x) {
for (const auto &block : pg) {
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()));
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize());
}
cpu::InvalidateEntireInstructionCache();
}
@ -2665,7 +2665,8 @@ namespace ams::kern {
/* Invalidate the block. */
if (cur_size > 0) {
MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
/* NOTE: Nintendo does not check the result of invalidation. */
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
}
/* Advance. */
@ -2688,7 +2689,8 @@ namespace ams::kern {
/* Invalidate the last block. */
if (cur_size > 0) {
MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
/* NOTE: Nintendo does not check the result of invalidation. */
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
}
R_SUCCEED();
@ -2766,7 +2768,7 @@ namespace ams::kern {
if (cur_size >= sizeof(u32)) {
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, copy_size));
cpu::FlushDataCache(copy_src, copy_size);
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(buffer, copy_src, copy_size), svc::ResultInvalidPointer());
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
cur_addr += copy_size;
@ -2776,7 +2778,7 @@ namespace ams::kern {
/* Copy remaining data. */
if (cur_size > 0) {
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, cur_size));
cpu::FlushDataCache(copy_src, cur_size);
R_UNLESS(UserspaceAccess::CopyMemoryToUser(buffer, copy_src, cur_size), svc::ResultInvalidPointer());
}
@ -2851,7 +2853,7 @@ namespace ams::kern {
if (cur_size >= sizeof(u32)) {
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned32Bit(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, copy_size), svc::ResultInvalidCurrentMemory());
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size));
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size);
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
cur_addr += copy_size;
@ -2861,7 +2863,7 @@ namespace ams::kern {
/* Copy remaining data. */
if (cur_size > 0) {
R_UNLESS(UserspaceAccess::CopyMemoryFromUser(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, cur_size), svc::ResultInvalidCurrentMemory());
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
}
R_SUCCEED();

View File

@ -404,7 +404,7 @@ namespace ams::kern {
void KProcess::DoWorkerTaskImpl() {
/* Terminate child threads. */
MESOSPHERE_R_ABORT_UNLESS(TerminateChildren(this, nullptr));
TerminateChildren(this, nullptr);
/* Finalize the handle table, if we're not immortal. */
if (!m_is_immortal && m_is_handle_table_initialized) {
@ -420,7 +420,7 @@ namespace ams::kern {
Result KProcess::StartTermination() {
/* Finalize the handle table when we're done, if the process isn't immortal. */
ON_RESULT_SUCCESS {
ON_SCOPE_EXIT {
if (!m_is_immortal) {
this->FinalizeHandleTable();
}
@ -471,7 +471,7 @@ namespace ams::kern {
/* If we need to start termination, do so. */
if (needs_terminate) {
static_cast<void>(this->StartTermination());
this->StartTermination();
/* Note for debug that we're exiting the process. */
MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name);
@ -507,18 +507,8 @@ namespace ams::kern {
/* If we need to terminate, do so. */
if (needs_terminate) {
/* If we fail to terminate, register as a worker task. */
ON_RESULT_FAILURE {
/* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
/* Register the process as a work task. */
KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this);
};
/* Start termination. */
R_TRY(this->StartTermination());
if (R_SUCCEEDED(this->StartTermination())) {
/* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() OK pid=%ld name=%-12s\n", m_process_id, m_name);
@ -527,6 +517,13 @@ namespace ams::kern {
/* Finish termination. */
this->FinishTermination();
} else {
/* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
/* Register the process as a work task. */
KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this);
}
}
R_SUCCEED();
@ -669,7 +666,7 @@ namespace ams::kern {
R_SUCCEED();
}
void KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
KThreadLocalPage *page_to_free = nullptr;
/* Release the region. */
@ -681,7 +678,7 @@ namespace ams::kern {
if (it == m_partially_used_tlp_tree.end()) {
/* If we don't find it, it has to be in the fully used list. */
it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize));
MESOSPHERE_ABORT_UNLESS(it != m_fully_used_tlp_tree.end());
R_UNLESS(it != m_fully_used_tlp_tree.end(), svc::ResultInvalidAddress());
/* Release the region. */
it->Release(addr);
@ -713,6 +710,8 @@ namespace ams::kern {
KThreadLocalPage::Free(page_to_free);
}
R_SUCCEED();
}
void *KProcess::GetThreadLocalRegionPointer(KProcessAddress addr) {
@ -768,7 +767,7 @@ namespace ams::kern {
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
if (const auto prev = m_num_running_threads--; prev == 1) {
static_cast<void>(this->Terminate());
this->Terminate();
}
}

View File

@ -46,7 +46,7 @@ namespace ams::kern {
}
}
void KReadableEvent::Signal() {
Result KReadableEvent::Signal() {
MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock lk;
@ -55,6 +55,8 @@ namespace ams::kern {
m_is_signaled = true;
this->NotifyAvailable();
}
R_SUCCEED();
}
Result KReadableEvent::Reset() {

View File

@ -65,7 +65,7 @@ namespace ams::kern {
}
/* Bind interrupt handler. */
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false);
/* Set the current thread. */
m_current_thread = GetCurrentThreadPointer();
@ -270,13 +270,7 @@ namespace ams::kern {
m_current_thread = next_thread;
/* Set the new Thread Local region. */
const auto tls_address = GetInteger(next_thread->GetThreadLocalRegionAddress());
cpu::SwitchThreadLocalRegion(tls_address);
/* Update the thread's cpu time differential in TLS, if relevant. */
if (tls_address != 0) {
static_cast<ams::svc::ThreadLocalRegion *>(next_thread->GetThreadLocalRegionHeapAddress())->thread_cpu_time = next_thread->GetCpuTime() - cur_tick;
}
cpu::SwitchThreadLocalRegion(GetInteger(next_thread->GetThreadLocalRegionAddress()));
}
void KScheduler::ClearPreviousThread(KThread *thread) {

View File

@ -476,8 +476,8 @@ namespace ams::kern {
/* Ensure that we clean up on failure. */
ON_RESULT_FAILURE {
static_cast<void>(dst_page_table.CleanupForIpcServer(dst_address, size, dst_state));
static_cast<void>(src_page_table.CleanupForIpcClient(src_address, size, dst_state));
dst_page_table.CleanupForIpcServer(dst_address, size, dst_state);
src_page_table.CleanupForIpcClient(src_address, size, dst_state);
};
/* Push the appropriate mapping. */
@ -582,7 +582,7 @@ namespace ams::kern {
/* Set up a guard to make sure that we end up in a clean state on error. */
ON_RESULT_FAILURE {
/* Cleanup mappings. */
static_cast<void>(CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table)));
CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table));
/* Cleanup special data. */
if (src_header.GetHasSpecialHeader()) {
@ -835,11 +835,11 @@ namespace ams::kern {
CleanupSpecialData(dst_process, dst_msg_ptr, dst_buffer_size);
}
} else {
static_cast<void>(CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr));
CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr);
}
/* Cleanup mappings. */
static_cast<void>(CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table)));
CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table));
};
/* Ensure that the headers fit. */
@ -1052,7 +1052,7 @@ namespace ams::kern {
/* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */
static_cast<void>(client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size));
client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size);
/* Signal the event. */
event->Signal();
@ -1156,7 +1156,7 @@ namespace ams::kern {
/* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */
static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
/* Signal the event. */
event->Signal();
@ -1284,7 +1284,7 @@ namespace ams::kern {
/* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */
static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
/* Signal the event. */
event->Signal();
@ -1383,7 +1383,7 @@ namespace ams::kern {
/* Unlock the buffer. */
/* NOTE: Nintendo does not check the result of this. */
static_cast<void>(client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize()));
client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize());
/* Signal the event. */
event->Signal();

View File

@ -42,7 +42,7 @@ namespace ams::kern {
R_UNLESS(m_resource_size > rc_size, svc::ResultOutOfMemory());
/* Initialize slab heaps. */
R_TRY(m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, PageSize));
m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, PageSize);
m_page_table_heap.Initialize(std::addressof(m_dynamic_page_manager), 0, GetPointer<KPageTableManager::RefCount>(m_resource_address));
m_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
m_block_info_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);

View File

@ -392,7 +392,7 @@ namespace ams::kern {
/* If the thread has a local region, delete it. */
if (m_tls_address != Null<KProcessAddress>) {
m_parent->DeleteThreadLocalRegion(m_tls_address);
MESOSPHERE_R_ABORT_UNLESS(m_parent->DeleteThreadLocalRegion(m_tls_address));
}
/* Release any waiters. */
@ -697,7 +697,7 @@ namespace ams::kern {
R_SUCCEED();
}
void KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) {
Result KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) {
MESOSPHERE_ASSERT_THIS();
{
KScopedSchedulerLock sl;
@ -712,6 +712,8 @@ namespace ams::kern {
*out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask();
}
}
R_SUCCEED();
}
Result KThread::SetCoreMask(int32_t core_id, u64 v_affinity_mask) {
@ -850,7 +852,7 @@ namespace ams::kern {
}
}
void KThread::SetPriorityToIdle() {
Result KThread::SetPriorityToIdle() {
MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock sl;
@ -860,6 +862,8 @@ namespace ams::kern {
m_priority = IdleThreadPriority;
m_base_priority = IdleThreadPriority;
KScheduler::OnThreadPriorityChanged(this, old_priority);
R_SUCCEED();
}
void KThread::RequestSuspend(SuspendType type) {
@ -1403,7 +1407,7 @@ namespace ams::kern {
return this->GetState();
}
void KThread::Sleep(s64 timeout) {
Result KThread::Sleep(s64 timeout) {
MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread());
MESOSPHERE_ASSERT(this == GetCurrentThreadPointer());
@ -1418,13 +1422,15 @@ namespace ams::kern {
/* Check if the thread should terminate. */
if (this->IsTerminationRequested()) {
slp.CancelSleep();
return;
R_THROW(svc::ResultTerminationRequested());
}
/* Wait for the sleep to end. */
wait_queue.SetHardwareTimer(timer);
this->BeginWait(std::addressof(wait_queue));
}
R_SUCCEED();
}
void KThread::BeginWait(KThreadQueue *queue) {

View File

@ -32,7 +32,7 @@ namespace ams::kern {
R_RETURN(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, page_buf->GetPhysicalAddress(), KMemoryState_ThreadLocal, KMemoryPermission_UserReadWrite));
}
void KThreadLocalPage::Finalize() {
Result KThreadLocalPage::Finalize() {
MESOSPHERE_ASSERT_THIS();
/* Get the physical address of the page. */
@ -40,10 +40,11 @@ namespace ams::kern {
MESOSPHERE_ABORT_UNLESS(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), this->GetAddress()));
/* Unmap the page. */
MESOSPHERE_R_ABORT_UNLESS(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal));
R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal));
/* Free the page. */
KPageBuffer::FreeChecked<PageSize>(KPageBuffer::FromPhysicalAddress(phys_addr));
R_SUCCEED();
}
KProcessAddress KThreadLocalPage::Reserve() {

View File

@ -67,7 +67,7 @@ namespace ams::kern {
KThread::Register(thread);
/* Run the thread. */
MESOSPHERE_R_ABORT_UNLESS(thread->Run());
thread->Run();
}
void KWorkerTaskManager::AddTask(WorkerType type, KWorkerTask *task) {

View File

@ -52,8 +52,8 @@ namespace ams::kern {
void *idle_thread_stack = GetVoidPointer(KMemoryLayout::GetIdleStackTopAddress(core_id));
KAutoObject::Create<KThread>(main_thread);
KAutoObject::Create<KThread>(idle_thread);
MESOSPHERE_R_ABORT_UNLESS(main_thread->Initialize(nullptr, 0, main_thread_stack, 0, KThread::MainThreadPriority, core_id, nullptr, KThread::ThreadType_Main));
MESOSPHERE_R_ABORT_UNLESS(idle_thread->Initialize(nullptr, 0, idle_thread_stack, 0, KThread::IdleThreadPriority, core_id, nullptr, KThread::ThreadType_Main));
main_thread->Initialize(nullptr, 0, main_thread_stack, 0, KThread::MainThreadPriority, core_id, nullptr, KThread::ThreadType_Main);
idle_thread->Initialize(nullptr, 0, idle_thread_stack, 0, KThread::IdleThreadPriority, core_id, nullptr, KThread::ThreadType_Main);
/* Set the current thread to be the main thread, and we have no processes running yet. */
SetCurrentThread(main_thread);
@ -79,7 +79,7 @@ namespace ams::kern {
KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
/* Initialize the resource managers' shared page manager. */
MESOSPHERE_R_ABORT_UNLESS(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. */
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);

View File

@ -131,7 +131,7 @@ namespace ams::kern::svc {
} else {
class StoreCacheOperation : public CacheOperation {
public:
virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(address, size)); }
virtual void Operate(void *address, size_t size) const override { cpu::StoreDataCache(address, size); }
} operation;
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
@ -158,7 +158,7 @@ namespace ams::kern::svc {
} else {
class FlushCacheOperation : public CacheOperation {
public:
virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(address, size)); }
virtual void Operate(void *address, size_t size) const override { cpu::FlushDataCache(address, size); }
} operation;
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));

View File

@ -29,8 +29,7 @@ namespace ams::kern::svc {
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
R_UNLESS(event.IsNotNull(), svc::ResultInvalidHandle());
event->Signal();
R_SUCCEED();
R_RETURN(event->Signal());
}
Result ClearEvent(ams::svc::Handle event_handle) {
@ -41,8 +40,7 @@ namespace ams::kern::svc {
{
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
if (event.IsNotNull()) {
event->Clear();
R_SUCCEED();
R_RETURN(event->Clear());
}
}
@ -51,11 +49,10 @@ namespace ams::kern::svc {
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
if (readable_event.IsNotNull()) {
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
interrupt_event->Clear();
R_RETURN(interrupt_event->Clear());
} else {
readable_event->Clear();
R_RETURN(readable_event->Clear());
}
R_SUCCEED();
}
}

View File

@ -148,7 +148,7 @@ namespace ams::kern::svc {
{
/* If we fail to send the message, unlock the message buffer. */
ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); };
/* Send the request. */
MESOSPHERE_ASSERT(message != 0);
@ -220,7 +220,7 @@ namespace ams::kern::svc {
/* Ensure that if we fail and aren't terminating that we unlock the user buffer. */
ON_RESULT_FAILURE_BESIDES(svc::ResultTerminationRequested) {
static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size));
page_table.UnlockForIpcUserBuffer(message, buffer_size);
};
/* Send the request. */
@ -248,7 +248,7 @@ namespace ams::kern::svc {
{
/* If we fail to send the message, unlock the message buffer. */
ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); };
/* Reply/Receive the request. */
MESOSPHERE_ASSERT(message != 0);

View File

@ -165,14 +165,14 @@
HANDLER(NvHostErrInfo, 124 ) \
HANDLER(RunningUlaInfo, 125 ) \
HANDLER(InternalPanelInfo, 126 ) \
HANDLER(ResourceLimitInfo, 127 ) \
HANDLER(ResourceLimitPeakInfoDeprecated, 128 ) \
HANDLER(ResourceLimitLimitInfo, 127 ) \
HANDLER(ResourceLimitPeakInfo, 128 ) \
HANDLER(TouchScreenInfo, 129 ) \
HANDLER(AcpUserAccountSettingsInfo, 130 ) \
HANDLER(AudioDeviceInfo, 131 ) \
HANDLER(AbnormalWakeInfo, 132 ) \
HANDLER(ServiceProfileInfo, 133 ) \
HANDLER(BluetoothAudioInfoDeprecated, 134 ) \
HANDLER(BluetoothAudioInfo, 134 ) \
HANDLER(BluetoothPairingCountInfo, 135 ) \
HANDLER(FsProxyErrorInfo2, 136 ) \
HANDLER(BuiltInWirelessOUIInfo, 137 ) \
@ -188,17 +188,9 @@
HANDLER(WlanIoctlErrorInfo, 147 ) \
HANDLER(SdCardActivationInfo, 148 ) \
HANDLER(GameCardDetailedErrorInfo, 149 ) \
HANDLER(NetworkInfo2, 150 ) \
HANDLER(SystemSettingInfo, 151 ) \
HANDLER(MigrationStateInfo, 152 ) \
HANDLER(WinVdInfo, 153 ) \
HANDLER(PscTransitionStateInfo, 154 ) \
HANDLER(FsProxyErrorInfo3, 155 ) \
HANDLER(BluetoothErrorInfo, 156 ) \
HANDLER(TestNx, 1000) \
HANDLER(NANDTypeInfo, 1001) \
HANDLER(NANDExtendedCsd, 1002) \
HANDLER(BluetoothAudioInfo, 1003)
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
@ -819,16 +811,16 @@
HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountLimit, 619, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountLimit, 620, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountLimit, 622, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountPeak, 624, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountPeak, 625, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountPeak, 627, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \
@ -847,7 +839,7 @@
HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(BluetoothAudioConnectionCountDeprecated, 646, BluetoothAudioInfoDeprecated, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothHidPairingInfoCountDeprecated, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothAudioPairingInfoCountDeprecated, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothLePairingInfoCountDeprecated, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
@ -935,45 +927,6 @@
HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(GameCardPreviousInsertedTimestamp, 734, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(WlanChipResetTriggered, 735, WlanInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(NANDNumReadFailures, 736, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDNumReadRecoveries, 737, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDNumWriteFailures, 738, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDNumWriteRecoveries, 739, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(WlanCommandEventHistoryV2, 740, WlanInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(WlanChipResetReason, 741, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(WlanAssertDumpData, 742, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ApplicationErrorFlag, 743, ApplicationInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(FsOrphanedSaveDataTotalSize, 744, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FsOrphanedSaveDataCount, 745, FsProxyErrorInfo2, FieldType_NumericU16, FieldFlag_None ) \
HANDLER(MigrationType, 746, MigrationStateInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(MigrationResumeCount, 747, MigrationStateInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(MigrationStateData, 748, MigrationStateInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(WinVdPcEnvironment, 749, WinVdInfo, FieldType_String, FieldFlag_None ) \
HANDLER(PscBlockingPmModuleList, 750, PscTransitionStateInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(CrashReportFlag, 751, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(TouchScreenPanelVendor, 752, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(GameCardReportMiscFlags, 753, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(GameCardRemovedTimestamp, 754, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(GameCardPackageId, 755, GameCardDetailedErrorInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(GameCardInserted, 756, GameCardDetailedErrorInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(ErptStartupCount, 757, ErrorInfoAuto, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardTotalNumberOfLogicalClusters, 758, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardBytePerLogicalSector, 759, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardLogicalSectorPerCluster, 760, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardFormatType, 761, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(FatSdCardNumberOfFat, 762, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(FatSdCardSectorPerFat, 763, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardNumberOfReservedSectors, 764, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardFirstDataSector, 765, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FatSdCardTotalNumberOfSectors, 766, FsProxyErrorInfo3, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(FatSdCardCheckFlags, 767, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(BluetoothHaltedReason, 768, ErrorInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothHaltedCurrentPmState, 769, ErrorInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothHaltedRequestedPmState, 770, ErrorInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BluetoothHaltedBtpApiFailedId, 771, ErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
HANDLER(RomFsRecoveredAesFailedCount, 772, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(DriverRecoveredAesFailedCount, 773, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(BluetoothIsHalted, 774, BluetoothErrorInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \
HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
@ -1008,5 +961,4 @@
HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(BluetoothAudioConnectionCount, 1034, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None )

View File

@ -194,12 +194,6 @@ namespace ams::erpt {
};
};
struct CategoryEntry {
CategoryId category;
u32 field_count;
u32 array_buffer_count;
};
constexpr inline u32 FieldsPerContext = 20;
struct ContextEntry {
u32 version;

View File

@ -27,13 +27,9 @@
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, CreateReportWithAdditionalContext, (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, const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags, category_entries, field_entries, array_buffer), hos::Version_21_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, SubmitMultipleContext, (const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer), (category_entries, field_entries, array_buffer), hos::Version_21_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0, hos::Version_20_5_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, RegisterRunningApplicationInfo, (ncm::ApplicationId app_id, ncm::ProgramId program_id), (app_id, program_id), hos::Version_21_0_0) \
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0, hos::Version_20_5_0) \
AMS_SF_METHOD_INFO(C, H, 8, Result, UnregisterRunningApplicationInfo, (), (), hos::Version_21_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \
@ -45,8 +41,7 @@
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 40, Result, WaitForReportCreation, (), (), hos::Version_21_0_0)
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0)
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)

View File

@ -124,10 +124,6 @@ namespace ams::erpt::srv {
}
}
constexpr inline bool IsValidCategory(CategoryId id) {
return FindCategoryIndex(id).has_value();
}
constexpr inline CategoryId ConvertFieldToCategory(FieldId id) {
const auto index = FindFieldIndex(id);
AMS_ASSERT(index.has_value());

View File

@ -24,7 +24,7 @@ namespace ams::fatal {
enum FatalPolicy : u32 {
FatalPolicy_ErrorReportAndErrorScreen = 0,
FatalPolicy_ErrorReport = 1,
FatalPolicy_ErrorScreen = 2,
FatalPolicy_ErrorScreen = 2
};
#if defined(ATMOSPHERE_ARCH_ARM64)
@ -470,14 +470,6 @@ namespace ams::fatal {
#endif
static_assert(util::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
struct HashedTraceContext {
u8 data[0x20];
u32 data_count;
};
static_assert(util::is_pod<HashedTraceContext>::value);
static_assert(sizeof(HashedTraceContext) == 0x24);
static_assert(alignof(HashedTraceContext) == 0x4);
namespace srv {
struct ThrowContext {
@ -488,7 +480,6 @@ namespace ams::fatal {
char proc_name[0xD];
bool is_creport;
CpuContext cpu_ctx;
HashedTraceContext hashed_trace_ctx;
bool generate_error_report;
os::Event *erpt_event;
os::Event *battery_event;
@ -499,7 +490,7 @@ namespace ams::fatal {
u8 tls_dump[0x100];
ThrowContext(os::Event *erpt, os::Event *bat)
: result(ResultSuccess()), policy(), program_id(), throw_program_id(), proc_name(), is_creport(), cpu_ctx(), hashed_trace_ctx(), generate_error_report(),
: result(ResultSuccess()), policy(), program_id(), throw_program_id(), proc_name(), is_creport(), cpu_ctx(), generate_error_report(),
erpt_event(erpt), battery_event(bat),
stack_dump_size(), stack_dump_base(), stack_dump(), tls_address(), tls_dump()
{

View File

@ -22,7 +22,6 @@
#define AMS_FATAL_I_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, ThrowFatal, (Result error, const sf::ClientProcessId &client_pid), (error, client_pid)) \
AMS_SF_METHOD_INFO(C, H, 1, Result, ThrowFatalWithPolicy, (Result error, const sf::ClientProcessId &client_pid, fatal::FatalPolicy policy), (error, client_pid, policy)) \
AMS_SF_METHOD_INFO(C, H, 2, Result, ThrowFatalWithCpuContext, (Result error, const sf::ClientProcessId &client_pid, fatal::FatalPolicy policy, const fatal::CpuContext &cpu_ctx), (error, client_pid, policy, cpu_ctx)) \
AMS_SF_METHOD_INFO(C, H, 3, Result, ThrowFatalWithHashedTraceContext, (Result error, const sf::ClientProcessId &client_pid, ncm::ProgramId program_id, const fatal::HashedTraceContext &htc), (error, client_pid, program_id, htc))
AMS_SF_METHOD_INFO(C, H, 2, Result, ThrowFatalWithCpuContext, (Result error, const sf::ClientProcessId &client_pid, fatal::FatalPolicy policy, const fatal::CpuContext &cpu_ctx), (error, client_pid, policy, cpu_ctx))
AMS_SF_DEFINE_INTERFACE(ams::fatal::impl, IService, AMS_FATAL_I_SERVICE_INTERFACE_INFO, 0x91328766)

View File

@ -90,15 +90,6 @@ namespace ams::hos {
Version_20_0_0 = ::ams::TargetFirmware_20_0_0,
Version_20_0_1 = ::ams::TargetFirmware_20_0_1,
Version_20_1_0 = ::ams::TargetFirmware_20_1_0,
Version_20_1_1 = ::ams::TargetFirmware_20_1_1,
Version_20_1_5 = ::ams::TargetFirmware_20_1_5,
Version_20_2_0 = ::ams::TargetFirmware_20_2_0,
Version_20_3_0 = ::ams::TargetFirmware_20_3_0,
Version_20_4_0 = ::ams::TargetFirmware_20_4_0,
Version_20_5_0 = ::ams::TargetFirmware_20_5_0,
Version_21_0_0 = ::ams::TargetFirmware_21_0_0,
Version_21_0_1 = ::ams::TargetFirmware_21_0_1,
Version_21_1_0 = ::ams::TargetFirmware_21_1_0,
Version_Current = ::ams::TargetFirmware_Current,

View File

@ -100,7 +100,6 @@ namespace ams::ldr {
Flag_CheckHashText = (1 << 3),
Flag_CheckHashRo = (1 << 4),
Flag_CheckHashRw = (1 << 5),
Flag_PreventCodeReads = (1 << 6),
};
struct SegmentInfo {
@ -181,8 +180,6 @@ namespace ams::ldr {
AcidFlag_PoolPartitionShift = 2,
AcidFlag_PoolPartitionMask = (0xF << AcidFlag_PoolPartitionShift),
AcidFlag_LoadBrowserCoreDll = (1 << 7),
};
enum PoolPartition {

View File

@ -422,7 +422,7 @@ namespace ams::ncm {
public:
void Reset() {
if (m_accessor != nullptr) {
static_cast<void>(m_accessor->ReleasePin(m_pin_id));
m_accessor->ReleasePin(m_pin_id);
m_accessor = nullptr;
}
}
@ -479,7 +479,7 @@ namespace ams::ncm {
/* Mark the memory as in use. */
R_RETURN(m_mapper->MarkUsing(memory.id));
ON_SCOPE_EXIT { static_cast<void>(this->ReleasePin(memory.id)); };
ON_SCOPE_EXIT { this->ReleasePin(memory.id); };
/* Copy out the struct. */
*out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T)));

View File

@ -102,8 +102,6 @@ namespace ams::ncm {
static const SystemProgramId End;
static const SystemProgramId BrowserCoreDll;
static const SystemProgramId Manu;
static const SystemProgramId Htc;
static const SystemProgramId DmntGen2;
@ -214,8 +212,6 @@ namespace ams::ncm {
inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul };
inline constexpr const SystemProgramId SystemProgramId::BrowserCoreDll = { 0x010000000000085Dul };
inline constexpr const SystemProgramId SystemProgramId::Manu = { 0x010000000000B14Aul };
inline constexpr const SystemProgramId SystemProgramId::Htc = { 0x010000000000B240ul };
inline constexpr const SystemProgramId SystemProgramId::DmntGen2 = { 0x010000000000D609ul };

View File

@ -32,7 +32,6 @@
AMS_SF_METHOD_INFO(C, H, 8, Result, EnableApplicationCrashReport, (bool enabled), (enabled)) \
AMS_SF_METHOD_INFO(C, H, 9, Result, IsApplicationCrashReportEnabled, (ams::sf::Out<bool> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled), (enabled)) \
AMS_SF_METHOD_INFO(C, H, 11, Result, GetProcessId, (ams::sf::Out<os::ProcessId> out, ncm::ProgramId program_id), (out, program_id)) \
AMS_SF_METHOD_INFO(C, H, 12, Result, TriggerApplicationSnapShotDumper, (pgl::SnapShotDumpType dump_type, const ams::sf::InBuffer &arg), (dump_type, arg)) \
AMS_SF_METHOD_INFO(C, H, 20, Result, GetShellEventObserver, (ams::sf::Out<ams::sf::SharedPointer<pgl::sf::IEventObserver>> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 21, Result, Command21NotImplemented, (ams::sf::Out<u64> out, u32 in, const ams::sf::InBuffer &buf1, const ams::sf::InBuffer &buf2), (out, in, buf1, buf2), hos::Version_11_0_0)

View File

@ -37,7 +37,6 @@ namespace ams::pgl::srv {
Result EnableApplicationCrashReportImpl(bool enabled);
Result IsApplicationCrashReportEnabledImpl(bool *out);
Result EnableApplicationAllThreadDumpOnCrashImpl(bool enabled);
Result GetProcessId(os::ProcessId *out, ncm::ProgramId program_id);
Result TriggerApplicationSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size);
};
@ -63,7 +62,6 @@ namespace ams::pgl::srv {
Result EnableApplicationCrashReport(bool enabled);
Result IsApplicationCrashReportEnabled(ams::sf::Out<bool> out);
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
Result GetProcessId(ams::sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg);
Result GetShellEventObserver(ams::sf::Out<ams::sf::SharedPointer<pgl::sf::IEventObserver>> out);
@ -88,7 +86,6 @@ namespace ams::pgl::srv {
Result EnableApplicationCrashReport(bool enabled);
Result IsApplicationCrashReportEnabled(ams::tipc::Out<bool> out);
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
Result GetProcessId(ams::tipc::Out<os::ProcessId> out, ncm::ProgramId program_id);
Result GetShellEventObserver(ams::tipc::OutMoveHandle out);
};
static_assert(pgl::tipc::IsIShellInterface<ShellInterfaceTipc>);

View File

@ -30,8 +30,7 @@
AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \
AMS_SF_METHOD_INFO(C, H, 8, Result, BoostApplicationThreadResourceLimit, (), ()) \
AMS_SF_METHOD_INFO(C, H, 9, void, GetBootFinishedEventHandle, (sf::OutCopyHandle out), (out), hos::Version_8_0_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) \
AMS_SF_METHOD_INFO(C, H, 12, Result, GetProcessId, (sf::Out<os::ProcessId> out, ncm::ProgramId program_id), (out, program_id))
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ())
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
@ -46,7 +45,6 @@ AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE
AMS_SF_METHOD_INFO(C, H, 7, void, NotifyBootFinished, (), ()) \
AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 9, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size), hos::Version_4_0_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) \
AMS_SF_METHOD_INFO(C, H, 12, Result, GetProcessId, (sf::Out<os::ProcessId> out, ncm::ProgramId program_id), (out, program_id))
AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ())
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)

View File

@ -31,6 +31,5 @@ namespace ams::pm::shell {
Result BoostSystemMemoryResourceLimit(u64 size);
Result BoostApplicationThreadResourceLimit();
Result BoostSystemThreadResourceLimit();
Result GetProcessId(os::ProcessId *out_process_id, const ncm::ProgramId program_id);
}

View File

@ -34,7 +34,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
endif
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto -Wno-error=unused-result
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
@ -118,7 +118,7 @@ clean:
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@

View File

@ -20,7 +20,7 @@ namespace ams::cs {
void InitializeTargetIoServer() {
/* Launch target io server. */
os::ProcessId process_id;
static_cast<void>(scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0));
scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0);
}
}

View File

@ -35,9 +35,7 @@ namespace ams::erpt::srv {
Attachment::~Attachment() {
this->CloseStream();
if (m_record->RemoveReference()) {
if (R_FAILED(this->DeleteStream(this->FileName().name))) {
/* TODO: Log failure? */
}
this->DeleteStream(this->FileName().name);
delete m_record;
}
}

View File

@ -81,7 +81,7 @@ namespace ams::erpt::srv {
oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt));
}
R_TRY(Formatter::AddField(report, FieldId_CipherKey, cipher, s_need_to_store_cipher ? sizeof(cipher) : 1));
Formatter::AddField(report, FieldId_CipherKey, cipher, sizeof(cipher));
std::memset(s_key, 0, sizeof(s_key));
R_RETURN(Formatter::End(report));

View File

@ -90,15 +90,16 @@ namespace ams::erpt::srv {
Result Context::WriteContextsToReport(Report *report) {
R_TRY(report->Open(ReportOpenType_Create));
ON_SCOPE_EXIT { report->Close(); };
R_TRY(Cipher::Begin(report, ContextRecord::GetRecordCount()));
for (auto it = g_category_list.begin(); it != g_category_list.end(); it++) {
R_TRY(it->AddCategoryToReport(report));
}
R_RETURN(Cipher::End(report));
Cipher::End(report);
report->Close();
R_SUCCEED();
}
Result Context::ClearContext(CategoryId cat) {

View File

@ -23,59 +23,6 @@
namespace ams::erpt::srv {
namespace {
ContextEntry MakeContextEntry(const CategoryEntry &cat_entry, Span<const FieldEntry> field_entries) {
/* Check pre-conditions. */
AMS_ASSERT(cat_entry.field_count <= field_entries.size());
/* Make the entry. */
ContextEntry entry = {};
entry.version = 0;
entry.category = cat_entry.category;
entry.field_count = cat_entry.field_count;
for (size_t i = 0; i < cat_entry.field_count; ++i) {
entry.fields[i] = field_entries[i];
}
return entry;
}
Result SubmitMultipleContextImpl(Span<const CategoryEntry> category_entries, Span<const FieldEntry> field_entries, Span<const u8> array_buf) {
/* Iterate over all category entries. */
size_t field_entry_offset = 0;
size_t array_buf_offset = 0;
for (const auto &category_entry : category_entries) {
/* Check that the category is valid. */
R_UNLESS(erpt::srv::IsValidCategory(category_entry.category), erpt::ResultInvalidArgument());
/* Check that there aren't too many fields for the category. */
R_UNLESS(category_entry.field_count <= FieldsPerContext, erpt::ResultInvalidArgument());
/* Check that there isn't too much data in the array buf. */
R_UNLESS(category_entry.array_buffer_count <= ArrayBufferSizeMax, erpt::ResultInvalidArgument());
/* Check that the fields/data fit into the provided buffer. */
R_UNLESS(category_entry.field_count + field_entry_offset <= field_entries.size(), erpt::ResultInvalidArgument());
R_UNLESS(category_entry.array_buffer_count + array_buf_offset <= array_buf.size_bytes(), erpt::ResultInvalidArgument());
/* Make the entry. */
const auto ctx_entry = MakeContextEntry(category_entry, field_entries.subspan(field_entry_offset, category_entry.field_count));
R_TRY(Context::SubmitContext(std::addressof(ctx_entry), array_buf.data() + array_buf_offset, category_entry.array_buffer_count));
/* Advance. */
field_entry_offset += category_entry.field_count;
array_buf_offset += category_entry.array_buffer_count;
}
/* We succeeded. */
R_SUCCEED();
}
}
Result ContextImpl::SubmitContext(const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer) {
const ContextEntry *ctx = reinterpret_cast<const ContextEntry *>( ctx_buffer.GetPointer());
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
@ -138,28 +85,6 @@ namespace ams::erpt::srv {
R_SUCCEED();
}
Result ContextImpl::CreateReportWithAdditionalContext(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, const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer) {
/* Submit the additional context. */
R_TRY(SubmitMultipleContextImpl(category_entries.ToSpan(), field_entries.ToSpan(), MakeSpan<const u8>(array_buffer.GetPointer(), array_buffer.GetSize())));
/* Clear the additional context when we're done. */
ON_SCOPE_EXIT {
const auto category_span = category_entries.ToSpan();
for (const auto &entry : category_span) {
if (erpt::srv::IsValidCategory(entry.category)) {
static_cast<void>(Context::ClearContext(entry.category));
}
}
};
/* Create the report. */
R_TRY(this->CreateReport(report_type, ctx_buffer, data_buffer, meta_buffer, result, flags));
/* We succeeded. */
R_SUCCEED();
}
Result ContextImpl::SubmitMultipleCategoryContext(const MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer) {
R_UNLESS(ctx_entry.category_count <= CategoriesPerMultipleCategoryContext, erpt::ResultInvalidArgument());
@ -189,10 +114,6 @@ namespace ams::erpt::srv {
R_SUCCEED();
}
Result ContextImpl::SubmitMultipleContext(const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer) {
R_RETURN(SubmitMultipleContextImpl(category_entries.ToSpan(), field_entries.ToSpan(), MakeSpan<const u8>(array_buffer.GetPointer(), array_buffer.GetSize())));
}
Result ContextImpl::UpdateApplicationLaunchTime() {
Reporter::UpdateApplicationLaunchTime();
R_SUCCEED();
@ -203,16 +124,6 @@ namespace ams::erpt::srv {
R_SUCCEED();
}
Result ContextImpl::RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id) {
Reporter::RegisterRunningApplicationInfo(app_id, program_id);
R_SUCCEED();
}
Result ContextImpl::UnregisterRunningApplicationInfo() {
Reporter::UnregisterRunningApplicationInfo();
R_SUCCEED();
}
Result ContextImpl::SubmitAttachment(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) {
const char *name = reinterpret_cast<const char *>(attachment_name.GetPointer());
const u8 *data = reinterpret_cast<const u8 *>(attachment_data.GetPointer());
@ -300,12 +211,7 @@ namespace ams::erpt::srv {
Result ContextImpl::InvalidateForcedShutdownDetection() {
/* NOTE: Nintendo does not check the result here. */
static_cast<void>(erpt::srv::InvalidateForcedShutdownDetection());
R_SUCCEED();
}
Result ContextImpl::WaitForReportCreation() {
/* This function currently does nothing. Maybe it only waits on Ounce? */
erpt::srv::InvalidateForcedShutdownDetection();
R_SUCCEED();
}

View File

@ -26,13 +26,9 @@ namespace ams::erpt::srv {
Result ClearInitialLaunchSettingsCompletionTime();
Result UpdatePowerOnTime();
Result UpdateAwakeTime();
Result CreateReportWithAdditionalContext(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, const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer);
Result SubmitMultipleCategoryContext(const MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer);
Result SubmitMultipleContext(const ams::sf::InMapAliasArray<erpt::CategoryEntry> &category_entries, const ams::sf::InMapAliasArray<erpt::FieldEntry> &field_entries, const ams::sf::InBuffer &array_buffer);
Result UpdateApplicationLaunchTime();
Result RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id);
Result ClearApplicationLaunchTime();
Result UnregisterRunningApplicationInfo();
Result SubmitAttachment(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data);
Result CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer);
Result CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result);
@ -45,7 +41,6 @@ namespace ams::erpt::srv {
Result UnregisterRunningApplet(ncm::ProgramId program_id);
Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration);
Result InvalidateForcedShutdownDetection();
Result WaitForReportCreation();
};
static_assert(erpt::sf::IsIContext<ContextImpl>);

View File

@ -228,27 +228,27 @@ namespace ams::erpt::srv {
/* Check if the forced shutdown context exists; if it doesn't, we should create an empty one. */
if (!IsForceShutdownDetected()) {
/* NOTE: Nintendo does not check result here. */
static_cast<void>(CreateForcedShutdownContext());
CreateForcedShutdownContext();
return;
}
/* Load the forced shutdown context. */
/* NOTE: Nintendo does not check that this succeeds. */
static_cast<void>(LoadForcedShutdownContext());
LoadForcedShutdownContext();
/* Create report for the forced shutdown. */
/* NOTE: Nintendo does not check that this succeeds. */
static_cast<void>(CreateReportForForcedShutdown());
CreateReportForForcedShutdown();
/* Clear the forced shutdown categories. */
/* NOTE: Nintendo does not check that this succeeds. */
static_cast<void>(Context::ClearContext(CategoryId_RunningApplicationInfo));
static_cast<void>(Context::ClearContext(CategoryId_RunningAppletInfo));
static_cast<void>(Context::ClearContext(CategoryId_FocusedAppletHistoryInfo));
Context::ClearContext(CategoryId_RunningApplicationInfo);
Context::ClearContext(CategoryId_RunningAppletInfo);
Context::ClearContext(CategoryId_FocusedAppletHistoryInfo);
/* Save the forced shutdown context. */
/* NOTE: Nintendo does not check that this succeeds. */
static_cast<void>(SaveForcedShutdownContext());
SaveForcedShutdownContext();
}
void FinalizeForcedShutdownDetection() {
@ -265,7 +265,7 @@ namespace ams::erpt::srv {
void SaveForcedShutdownContext() {
/* NOTE: Nintendo does not check that saving the report succeeds. */
static_cast<void>(SaveForcedShutdownContextImpl());
SaveForcedShutdownContextImpl();
}
void SubmitContextForForcedShutdownDetection(const ContextEntry *entry, const u8 *data, u32 data_size) {

View File

@ -42,7 +42,7 @@ namespace ams::erpt::srv {
/* Close and commit the stream. */
stream.CloseStream();
R_TRY(stream.CommitStream());
stream.CommitStream();
R_SUCCEED();
}

View File

@ -34,9 +34,7 @@ namespace ams::erpt::srv {
auto *record = std::addressof(*it);
it = s_attachment_list.erase(s_attachment_list.iterator_to(*record));
if (record->RemoveReference()) {
if (R_FAILED(Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name))) {
/* TODO: Log failure? */
}
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
delete record;
}
}
@ -68,9 +66,7 @@ namespace ams::erpt::srv {
/* Delete the object, if we should. */
if (record->RemoveReference()) {
const auto delete_res = Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
delete record;
}
} else {
@ -132,13 +128,12 @@ namespace ams::erpt::srv {
}
if (record->m_info.flags.Test<AttachmentFlag::HasOwner>() && JournalForReports::RetrieveRecord(record->m_info.owner_report_id) != nullptr) {
/* NOTE: Nintendo does not check the result of storing the new record... */
record_guard.Cancel();
R_TRY(StoreRecord(record));
StoreRecord(record);
} else {
/* If the attachment has no owner (or we deleted the report), delete the file associated with it. */
const auto delete_res = Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
}
}

View File

@ -29,9 +29,7 @@ namespace ams::erpt::srv {
auto *record = std::addressof(*it);
it = s_record_list.erase(s_record_list.iterator_to(*record));
if (record->RemoveReference()) {
if (R_FAILED(Stream::DeleteStream(Report::FileName(record->m_info.id, false).name))) {
/* TODO: Log failure? */
}
Stream::DeleteStream(Report::FileName(record->m_info.id, false).name);
delete record;
}
}
@ -67,14 +65,12 @@ namespace ams::erpt::srv {
/* Delete any attachments. */
if (force_delete_attachments || record->m_info.flags.Test<ReportFlag::HasAttachment>()) {
static_cast<void>(JournalForAttachments::DeleteAttachments(record->m_info.id));
JournalForAttachments::DeleteAttachments(record->m_info.id);
}
/* Delete the object, if we should. */
if (record->RemoveReference()) {
const auto delete_res = Stream::DeleteStream(Report::FileName(record->m_info.id, false).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
Stream::DeleteStream(Report::FileName(record->m_info.id, false).name);
delete record;
}
}
@ -168,7 +164,8 @@ namespace ams::erpt::srv {
record_guard.Cancel();
R_TRY(StoreRecord(record));
/* NOTE: Nintendo does not check the result of storing the new record... */
StoreRecord(record);
}
cleanup_guard.Cancel();

View File

@ -56,8 +56,8 @@ namespace ams::erpt::srv {
fs::DisableAutoSaveDataCreation();
/* Extend the system save data. */
/* NOTE: Nintendo used to not check the result of this; they do now, but . */
static_cast<void>(ExtendSystemSaveData());
/* NOTE: Nintendo does not check result of this. */
ExtendSystemSaveData();
R_TRY_CATCH(fs::MountSystemSaveData(ReportStoragePath, SystemSaveDataId)) {
R_CATCH(fs::ResultTargetNotFound) {
@ -97,7 +97,7 @@ namespace ams::erpt::srv {
}
if (report_count >= MinimumReportCountForCleanup) {
static_cast<void>(fs::CleanDirectoryRecursively(ReportOnSdStorageRootDirectoryPath));
fs::CleanDirectoryRecursively(ReportOnSdStorageRootDirectoryPath);
}
}
@ -110,9 +110,7 @@ namespace ams::erpt::srv {
AMS_ABORT_UNLESS(ctx != nullptr);
}
if (R_FAILED(Journal::Restore())) {
/* TODO: Nintendo deletes system savedata when this fails. Should we?. */
}
Journal::Restore();
Reporter::UpdatePowerOnTime();
Reporter::UpdateAwakeTime();

View File

@ -39,10 +39,11 @@ namespace ams::erpt::srv {
m_system_event.Signal();
}
void ManagerImpl::NotifyAll() {
Result ManagerImpl::NotifyAll() {
for (auto &manager : g_manager_list) {
manager.NotifyOne();
}
R_SUCCEED();
}
Result ManagerImpl::GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter) {

View File

@ -27,7 +27,7 @@ namespace ams::erpt::srv {
private:
void NotifyOne();
public:
static void NotifyAll();
static Result NotifyAll();
public:
Result GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter);
Result GetEvent(ams::sf::OutCopyHandle out);

View File

@ -41,9 +41,7 @@ namespace ams::erpt::srv {
Report::~Report() {
this->CloseStream();
if (m_record->RemoveReference()) {
if (R_FAILED(this->DeleteStream(this->FileName().name))) {
/* TODO: Log failure? */
}
this->DeleteStream(this->FileName().name);
delete m_record;
}
}

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