mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2026-03-01 05:04:39 +00:00
Compare commits
No commits in common. "master" and "1.9.4" have entirely different histories.
@ -1,39 +1,5 @@
|
||||
# Changelog
|
||||
## 1.10.2
|
||||
+ Basic support was added for 21.2.0.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.10.1
|
||||
+ Basic support was added for 21.1.0.
|
||||
+ A bug was fixed that caused some games (e.g. Tomb Raider definitive edition) to fail to launch.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 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
|
||||
## 1.9.3
|
||||
+ 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.
|
||||
|
||||
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emummc
|
||||
branch = develop
|
||||
commit = 8ab963b0b1c24b68de8e0c98c62c7822a9765bf3
|
||||
parent = 1e88f37892555da4c38ca6c95f43c56cc6bb87e6
|
||||
commit = a8e5f1a184aeb8ba884166a1e4f386088d4a6cf1
|
||||
parent = 409c3cf9e190dbb65fe76570954939cbe8a5eca0
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 21.2.0**
|
||||
**1.0.0 - 20.1.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
||||
16
emummc/source/FS/FS_offsets.c
vendored
16
emummc/source/FS/FS_offsets.c
vendored
@ -79,10 +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 "offsets/2120.h"
|
||||
#include "offsets/2120_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@ -173,10 +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);
|
||||
DEFINE_OFFSET_STRUCT(_2120);
|
||||
DEFINE_OFFSET_STRUCT(_2120_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@ -306,14 +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));
|
||||
case FS_VER_21_2_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_2120));
|
||||
case FS_VER_21_2_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_2120_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
||||
6
emummc/source/FS/FS_versions.h
vendored
6
emummc/source/FS/FS_versions.h
vendored
@ -116,12 +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_21_2_0,
|
||||
FS_VER_21_2_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
||||
59
emummc/source/FS/offsets/2100.h
vendored
59
emummc/source/FS/offsets/2100.h
vendored
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
||||
59
emummc/source/FS/offsets/2100_exfat.h
vendored
59
emummc/source/FS/offsets/2100_exfat.h
vendored
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
||||
59
emummc/source/FS/offsets/2120.h
vendored
59
emummc/source/FS/offsets/2120.h
vendored
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_2120_H__
|
||||
#define __FS_2120_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_2120_SDMMC_ACCESSOR_GC 0x1AC970
|
||||
#define FS_OFFSET_2120_SDMMC_ACCESSOR_SD 0x1AE980
|
||||
#define FS_OFFSET_2120_SDMMC_ACCESSOR_NAND 0x1ACFA0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_2120_SDMMC_WRAPPER_READ 0x1A8850
|
||||
#define FS_OFFSET_2120_SDMMC_WRAPPER_WRITE 0x1A88B0
|
||||
#define FS_OFFSET_2120_RTLD 0x2E1C0
|
||||
#define FS_OFFSET_2120_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
|
||||
|
||||
#define FS_OFFSET_2120_CLKRST_SET_MIN_V_CLK_RATE 0x1CB9B0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_2120_LOCK_MUTEX 0x1A17D0
|
||||
#define FS_OFFSET_2120_UNLOCK_MUTEX 0x1A1830
|
||||
|
||||
#define FS_OFFSET_2120_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A8810
|
||||
#define FS_OFFSET_2120_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A8830
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_2120_SD_MUTEX 0xFEE408
|
||||
#define FS_OFFSET_2120_NAND_MUTEX 0xFE9CF0
|
||||
#define FS_OFFSET_2120_ACTIVE_PARTITION 0xFE9D30
|
||||
#define FS_OFFSET_2120_SDMMC_DAS_HANDLE 0xFCBB18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_2120_SD_DAS_INIT 0x2B5C8
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_2120_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_2120_H__
|
||||
59
emummc/source/FS/offsets/2120_exfat.h
vendored
59
emummc/source/FS/offsets/2120_exfat.h
vendored
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_2120_EXFAT_EXFAT_H__
|
||||
#define __FS_2120_EXFAT_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_GC 0x1B7AD0
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_SD 0x1B9AE0
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_NAND 0x1B8100
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_READ 0x1B39B0
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_WRITE 0x1B3A10
|
||||
#define FS_OFFSET_2120_EXFAT_RTLD 0x2E1C0
|
||||
#define FS_OFFSET_2120_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
|
||||
|
||||
#define FS_OFFSET_2120_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D6B10
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_2120_EXFAT_LOCK_MUTEX 0x1AC930
|
||||
#define FS_OFFSET_2120_EXFAT_UNLOCK_MUTEX 0x1AC990
|
||||
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B3970
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1B3990
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_2120_EXFAT_SD_MUTEX 0xFFF408
|
||||
#define FS_OFFSET_2120_EXFAT_NAND_MUTEX 0xFFACF0
|
||||
#define FS_OFFSET_2120_EXFAT_ACTIVE_PARTITION 0xFFAD30
|
||||
#define FS_OFFSET_2120_EXFAT_SDMMC_DAS_HANDLE 0xFD8B18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_2120_EXFAT_SD_DAS_INIT 0x2B5C8
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_2120_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_2120_EXFAT_EXFAT_H__
|
||||
@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
||||
/* TODO: Update on next change of keys. */
|
||||
/* Mariko Development Master Kek Source. */
|
||||
.byte 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. */
|
||||
@ -193,5 +189,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */
|
||||
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
|
||||
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
|
||||
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
|
||||
.byte 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 /* 21.0.0 Device Master Kek Source. */
|
||||
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
|
||||
@ -94,7 +94,7 @@ namespace ams::secmon::boot {
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 21);
|
||||
static_assert(pkg1::KeyGeneration_Count == 20);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -602,7 +602,7 @@ namespace ams::nxboot {
|
||||
Print("\n");
|
||||
|
||||
if (R_SUCCEEDED(save_result)) {
|
||||
Print("Report saved to /atmosphere/fatal_errors/report_%016" PRIx64 ".bin\n", f_ctx->report_identifier);
|
||||
Print("Report saved to /atmosphere/fatal_errors/report_%016" PRIx64 ".bin", f_ctx->report_identifier);
|
||||
} else {
|
||||
Print("Failed to save report to the SD card! (%08" PRIx32 ")\n", save_result.GetValue());
|
||||
}
|
||||
|
||||
@ -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] = {};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -186,12 +186,6 @@ namespace ams::nxboot {
|
||||
FsVersion_20_1_0,
|
||||
FsVersion_20_1_0_Exfat,
|
||||
|
||||
FsVersion_21_0_0,
|
||||
FsVersion_21_0_0_Exfat,
|
||||
|
||||
FsVersion_21_2_0,
|
||||
FsVersion_21_2_0_Exfat,
|
||||
|
||||
FsVersion_Count,
|
||||
};
|
||||
|
||||
@ -290,12 +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 */
|
||||
|
||||
{ 0xAF, 0x1D, 0xBD, 0xC7, 0x82, 0x98, 0x3C, 0xBD }, /* FsVersion_21_2_0 */
|
||||
{ 0x56, 0x25, 0x17, 0xA1, 0x92, 0xC3, 0xC8, 0xF0 }, /* FsVersion_21_2_0_Exfat */
|
||||
};
|
||||
|
||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||
@ -697,18 +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:
|
||||
case FsVersion_21_2_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:
|
||||
case FsVersion_21_2_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;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = 9a8703e710760be8c88147d15414a1c581711625
|
||||
parent = eb34f9789c62745d87f37e76761b14d946bac300
|
||||
commit = bbd085442eb240f400ab26bd808ad18c42ceb103
|
||||
parent = 98bc030b37a24b76a130b418f846d2dabc47bf27
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
|
||||
@ -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'>;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 {
|
||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.GetClassToken());
|
||||
#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 {
|
||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.m_class_token);
|
||||
#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;
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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; }
|
||||
};
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -77,7 +77,7 @@ namespace ams::kern {
|
||||
}
|
||||
public:
|
||||
Result Initialize(KProcess *process);
|
||||
void Finalize();
|
||||
Result Finalize();
|
||||
|
||||
KProcessAddress Reserve();
|
||||
void Release(KProcessAddress addr);
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
entry.needs_clear = false;
|
||||
m_interrupt_controller.Enable(irq);
|
||||
}
|
||||
/* 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) {
|
||||
entry.needs_clear = false;
|
||||
m_interrupt_controller.Enable(irq);
|
||||
}
|
||||
/* 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.SetPriorityLevel(irq, entry.priority);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]))));
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -361,18 +361,10 @@ 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;
|
||||
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
|
||||
}
|
||||
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() {
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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,26 +507,23 @@ 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 {
|
||||
/* Start termination. */
|
||||
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);
|
||||
|
||||
/* Call the debug callback. */
|
||||
KDebug::OnTerminateProcess(this);
|
||||
|
||||
/* 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);
|
||||
};
|
||||
|
||||
/* Start termination. */
|
||||
R_TRY(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);
|
||||
|
||||
/* Call the debug callback. */
|
||||
KDebug::OnTerminateProcess(this);
|
||||
|
||||
/* Finish termination. */
|
||||
this->FinishTermination();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 )
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -20,33 +20,28 @@
|
||||
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
||||
#include <stratosphere/time/time_steady_clock_time_point.hpp>
|
||||
|
||||
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 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, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 40, Result, WaitForReportCreation, (), (), hos::Version_21_0_0)
|
||||
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -19,10 +19,9 @@
|
||||
#include <stratosphere/fatal/fatal_types.hpp>
|
||||
#include <stratosphere/sf.hpp>
|
||||
|
||||
#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))
|
||||
#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_DEFINE_INTERFACE(ams::fatal::impl, IService, AMS_FATAL_I_SERVICE_INTERFACE_INFO, 0x91328766)
|
||||
|
||||
@ -95,11 +95,6 @@ namespace ams::hos {
|
||||
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_21_2_0 = ::ams::TargetFirmware_21_2_0,
|
||||
|
||||
Version_Current = ::ams::TargetFirmware_Current,
|
||||
|
||||
|
||||
@ -94,13 +94,12 @@ namespace ams::ldr {
|
||||
};
|
||||
|
||||
enum Flag : u32 {
|
||||
Flag_CompressedText = (1 << 0),
|
||||
Flag_CompressedRo = (1 << 1),
|
||||
Flag_CompressedRw = (1 << 2),
|
||||
Flag_CheckHashText = (1 << 3),
|
||||
Flag_CheckHashRo = (1 << 4),
|
||||
Flag_CheckHashRw = (1 << 5),
|
||||
Flag_PreventCodeReads = (1 << 6),
|
||||
Flag_CompressedText = (1 << 0),
|
||||
Flag_CompressedRo = (1 << 1),
|
||||
Flag_CompressedRw = (1 << 2),
|
||||
Flag_CheckHashText = (1 << 3),
|
||||
Flag_CheckHashRo = (1 << 4),
|
||||
Flag_CheckHashRw = (1 << 5),
|
||||
};
|
||||
|
||||
struct SegmentInfo {
|
||||
@ -181,8 +180,6 @@ namespace ams::ldr {
|
||||
|
||||
AcidFlag_PoolPartitionShift = 2,
|
||||
AcidFlag_PoolPartitionMask = (0xF << AcidFlag_PoolPartitionShift),
|
||||
|
||||
AcidFlag_LoadBrowserCoreDll = (1 << 7),
|
||||
};
|
||||
|
||||
enum PoolPartition {
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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,12 +212,10 @@ 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 };
|
||||
inline constexpr const SystemProgramId SystemProgramId::DevServer = { 0x010000000000D623ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Manu = { 0x010000000000B14Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Htc = { 0x010000000000B240ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::DmntGen2 = { 0x010000000000D609ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::DevServer = { 0x010000000000D623ul };
|
||||
|
||||
inline constexpr bool IsSystemProgramId(const ProgramId &program_id) {
|
||||
return (SystemProgramId::Start <= program_id && program_id <= SystemProgramId::End) || IsAtmosphereProgramId(program_id);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result GetDebugEvent(::ams::svc::UserPointer< ::ams::svc::lp64::DebugEventInfo *> out_info, ::ams::svc::Handle debug_handle) {
|
||||
R_RETURN(::svcGetDebugEvent(reinterpret_cast<::DebugEventInfo *>(out_info.GetPointerUnsafe()), debug_handle));
|
||||
R_RETURN(::svcGetDebugEvent(out_info.GetPointerUnsafe(), debug_handle));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result ContinueDebugEvent(::ams::svc::Handle debug_handle, uint32_t flags, ::ams::svc::UserPointer<const uint64_t *> thread_ids, int32_t num_thread_ids) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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>);
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -42,7 +42,7 @@ namespace ams::erpt::srv {
|
||||
|
||||
/* Close and commit the stream. */
|
||||
stream.CloseStream();
|
||||
R_TRY(stream.CommitStream());
|
||||
stream.CommitStream();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,10 +44,8 @@ namespace ams::erpt::srv {
|
||||
static constexpr AppletActiveTimeInfo InvalidAppletActiveTimeInfo = { ncm::InvalidProgramId, os::Tick{}, TimeSpan::FromNanoSeconds(0) };
|
||||
private:
|
||||
std::array<AppletActiveTimeInfo, 8> m_list;
|
||||
ncm::ApplicationId m_running_app_id;
|
||||
ncm::ProgramId m_running_app_program_id;
|
||||
public:
|
||||
constexpr AppletActiveTimeInfoList() : m_list{InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo}, m_running_app_id{ncm::InvalidApplicationId}, m_running_app_program_id{ncm::InvalidProgramId} {
|
||||
constexpr AppletActiveTimeInfoList() : m_list{InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo} {
|
||||
m_list.fill(InvalidAppletActiveTimeInfo);
|
||||
}
|
||||
public:
|
||||
@ -69,32 +67,6 @@ namespace ams::erpt::srv {
|
||||
*entry = InvalidAppletActiveTimeInfo;
|
||||
}
|
||||
|
||||
void RegisterApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id) {
|
||||
/* Set the running application info. */
|
||||
m_running_app_id = app_id;
|
||||
m_running_app_program_id = program_id;
|
||||
}
|
||||
|
||||
void UnregisterApplicationInfo() {
|
||||
m_running_app_id = ncm::InvalidApplicationId;
|
||||
m_running_app_program_id = ncm::InvalidProgramId;
|
||||
}
|
||||
|
||||
util::optional<os::Tick> GetApplicationStartTick() {
|
||||
/* If we have a running application, try to find a matching entry. */
|
||||
if (m_running_app_id != ncm::InvalidApplicationId) {
|
||||
/* NOTE: This seems to be a Nintendo bug? They are comparing the running app id to the info's program id, */
|
||||
/* instead of the running app program id. Granted, these should usually be the same, but I think this code */
|
||||
/* is literally incorrect. */
|
||||
const auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == m_running_app_id; });
|
||||
if (entry != m_list.end()) {
|
||||
return entry->register_tick;
|
||||
}
|
||||
}
|
||||
|
||||
return util::nullopt;
|
||||
}
|
||||
|
||||
void UpdateSuspendedDuration(ncm::ProgramId program_id, TimeSpan suspended_duration) {
|
||||
/* Find a matching entry. */
|
||||
auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
|
||||
@ -152,19 +124,29 @@ namespace ams::erpt::srv {
|
||||
if (error_context_total_size == 0) {
|
||||
return;
|
||||
}
|
||||
static_cast<void>(record->Add(FieldId_ErrorContextTotalSize, error_context_total_size));
|
||||
record->Add(FieldId_ErrorContextTotalSize, error_context_total_size);
|
||||
|
||||
/* Set the context. */
|
||||
if (error_context_size == 0) {
|
||||
return;
|
||||
}
|
||||
static_cast<void>(record->Add(FieldId_ErrorContextSize, error_context_size));
|
||||
static_cast<void>(record->Add(FieldId_ErrorContext, error_context, error_context_size));
|
||||
record->Add(FieldId_ErrorContextSize, error_context_size);
|
||||
record->Add(FieldId_ErrorContext, error_context, error_context_size);
|
||||
}
|
||||
|
||||
void SubmitResourceLimitContexts() {
|
||||
constinit os::SdkMutex g_limit_mutex;
|
||||
constinit bool g_submitted_limit = false;
|
||||
|
||||
void SubmitResourceLimitLimitContext() {
|
||||
std::scoped_lock lk(g_limit_mutex);
|
||||
if (g_submitted_limit) {
|
||||
return;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { g_submitted_limit = true; };
|
||||
|
||||
/* Create and populate the record. */
|
||||
auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitInfo);
|
||||
auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitLimitInfo);
|
||||
if (record == nullptr) {
|
||||
return;
|
||||
}
|
||||
@ -183,15 +165,7 @@ namespace ams::erpt::srv {
|
||||
if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
|
||||
return; \
|
||||
} \
|
||||
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
s64 peak_value; \
|
||||
if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
|
||||
return; \
|
||||
} \
|
||||
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \
|
||||
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
@ -204,7 +178,51 @@ namespace ams::erpt::srv {
|
||||
|
||||
#undef ADD_RESOURCE
|
||||
|
||||
static_cast<void>(Context::SubmitContextRecord(std::move(record)));
|
||||
Context::SubmitContextRecord(std::move(record));
|
||||
|
||||
g_submitted_limit = true;
|
||||
}
|
||||
|
||||
void SubmitResourceLimitPeakContext() {
|
||||
/* Create and populate the record. */
|
||||
auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitPeakInfo);
|
||||
if (record == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
u64 reslimit_handle_value;
|
||||
if (R_FAILED(svc::GetInfo(std::addressof(reslimit_handle_value), svc::InfoType_ResourceLimit, svc::InvalidHandle, 0))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto handle = static_cast<svc::Handle>(reslimit_handle_value);
|
||||
ON_SCOPE_EXIT { R_ABORT_UNLESS(svc::CloseHandle(handle)); };
|
||||
|
||||
#define ADD_RESOURCE(__RESOURCE__) \
|
||||
do { \
|
||||
s64 peak_value; \
|
||||
if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
|
||||
return; \
|
||||
} \
|
||||
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
ADD_RESOURCE(PhysicalMemory);
|
||||
ADD_RESOURCE(ThreadCount);
|
||||
ADD_RESOURCE(EventCount);
|
||||
ADD_RESOURCE(TransferMemoryCount);
|
||||
ADD_RESOURCE(SessionCount);
|
||||
|
||||
#undef ADD_RESOURCE
|
||||
|
||||
Context::SubmitContextRecord(std::move(record));
|
||||
}
|
||||
|
||||
void SubmitResourceLimitContexts() {
|
||||
SubmitResourceLimitLimitContext();
|
||||
SubmitResourceLimitPeakContext();
|
||||
}
|
||||
#else
|
||||
void SubmitErrorContext(ContextRecord *record, Result result) {
|
||||
@ -244,11 +262,11 @@ namespace ams::erpt::srv {
|
||||
}
|
||||
|
||||
if (!found_abort_flag) {
|
||||
static_cast<void>(record->Add(FieldId_AbortFlag, false));
|
||||
record->Add(FieldId_AbortFlag, false);
|
||||
}
|
||||
|
||||
if (!found_syslog_flag) {
|
||||
static_cast<void>(record->Add(FieldId_HasSyslogFlag, true));
|
||||
record->Add(FieldId_HasSyslogFlag, true);
|
||||
}
|
||||
|
||||
R_TRY(Context::SubmitContextRecord(std::move(record)));
|
||||
@ -359,7 +377,7 @@ namespace ams::erpt::srv {
|
||||
|
||||
auto report = std::make_unique<Report>(record.get(), redirect_new_reports);
|
||||
R_UNLESS(report != nullptr, erpt::ResultOutOfMemory());
|
||||
auto report_guard = SCOPE_GUARD { const auto delete_res = report->Delete(); R_ASSERT(delete_res); AMS_UNUSED(delete_res); };
|
||||
auto report_guard = SCOPE_GUARD { report->Delete(); };
|
||||
|
||||
R_TRY(Context::WriteContextsToReport(report.get()));
|
||||
R_TRY(report->GetSize(std::addressof(record->m_info.report_size)));
|
||||
@ -396,14 +414,6 @@ namespace ams::erpt::srv {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Reporter::RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id) {
|
||||
g_applet_active_time_info_list.RegisterApplicationInfo(app_id, program_id);
|
||||
}
|
||||
|
||||
void Reporter::UnregisterRunningApplicationInfo() {
|
||||
g_applet_active_time_info_list.UnregisterApplicationInfo();
|
||||
}
|
||||
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
|
||||
/* Create a context record for the report. */
|
||||
auto record = std::make_unique<ContextRecord>();
|
||||
@ -419,9 +429,9 @@ namespace ams::erpt::srv {
|
||||
Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
|
||||
/* Clear the automatic categories, when we're done with our report. */
|
||||
ON_SCOPE_EXIT {
|
||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfo));
|
||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoAuto));
|
||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoDefaults));
|
||||
Context::ClearContext(CategoryId_ErrorInfo);
|
||||
Context::ClearContext(CategoryId_ErrorInfoAuto);
|
||||
Context::ClearContext(CategoryId_ErrorInfoDefaults);
|
||||
};
|
||||
|
||||
/* Get the context entry pointer. */
|
||||
@ -480,32 +490,28 @@ namespace ams::erpt::srv {
|
||||
R_ABORT_UNLESS(time::GetStandardSteadyClockCurrentTimePoint(std::addressof(steady_clock_current_timepoint)));
|
||||
|
||||
/* Add automatic fields. */
|
||||
static_cast<void>(auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))));
|
||||
static_cast<void>(auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))));
|
||||
static_cast<void>(auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))));
|
||||
static_cast<void>(auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))));
|
||||
static_cast<void>(auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value));
|
||||
static_cast<void>(auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value));
|
||||
static_cast<void>(auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible));
|
||||
static_cast<void>(auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value()));
|
||||
static_cast<void>(auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds));
|
||||
static_cast<void>(auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value));
|
||||
static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()));
|
||||
static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()));
|
||||
auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version)));
|
||||
auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version)));
|
||||
auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number)));
|
||||
auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str)));
|
||||
auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value);
|
||||
auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value);
|
||||
auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible);
|
||||
auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value());
|
||||
auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds);
|
||||
auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value);
|
||||
auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds());
|
||||
auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds());
|
||||
|
||||
if (s_initial_launch_settings_completion_time) {
|
||||
s64 elapsed_seconds;
|
||||
if (R_SUCCEEDED(time::GetElapsedSecondsBetween(std::addressof(elapsed_seconds), *s_initial_launch_settings_completion_time, steady_clock_current_timepoint))) {
|
||||
static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds));
|
||||
auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
if (hos::GetVersion() >= hos::Version_21_0_0) {
|
||||
if (auto start_tick = g_applet_active_time_info_list.GetApplicationStartTick(); start_tick.has_value()) {
|
||||
static_cast<void>(auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *start_tick).ToTimeSpan().GetSeconds()));
|
||||
}
|
||||
} else if (s_application_launch_time) {
|
||||
static_cast<void>(auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()));
|
||||
if (s_application_launch_time) {
|
||||
auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds());
|
||||
}
|
||||
|
||||
/* Submit applet active duration information. */
|
||||
@ -529,7 +535,7 @@ namespace ams::erpt::srv {
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test<CreateReportOptionFlag::SubmitFsInfo>()) {
|
||||
/* NOTE: Nintendo ignores the result of this call. */
|
||||
static_cast<void>(SubmitFsInfo());
|
||||
SubmitFsInfo();
|
||||
}
|
||||
#else
|
||||
AMS_UNUSED(flags);
|
||||
|
||||
@ -54,9 +54,6 @@ namespace ams::erpt::srv {
|
||||
static Result UnregisterRunningApplet(ncm::ProgramId program_id);
|
||||
static Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpan duration);
|
||||
|
||||
static void RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id);
|
||||
static void UnregisterRunningApplicationInfo();
|
||||
|
||||
static void SetRedirectNewReportsToSdCard(bool en) { s_redirect_new_reports = en; }
|
||||
private:
|
||||
static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp, erpt::CreateReportOptionFlagSet flags);
|
||||
|
||||
@ -36,10 +36,7 @@ namespace ams::erpt::srv {
|
||||
|
||||
std::scoped_lock lk(s_fs_commit_mutex);
|
||||
|
||||
const auto commit_res = fs::CommitSaveData(ReportStoragePath);
|
||||
R_ASSERT(commit_res);
|
||||
AMS_UNUSED(commit_res);
|
||||
|
||||
fs::CommitSaveData(ReportStoragePath);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@ -84,7 +81,7 @@ namespace ams::erpt::srv {
|
||||
} R_END_TRY_CATCH;
|
||||
break;
|
||||
}
|
||||
R_TRY(fs::SetFileSize(m_file_handle, 0));
|
||||
fs::SetFileSize(m_file_handle, 0);
|
||||
} else {
|
||||
R_UNLESS(mode == StreamMode_Read, erpt::ResultInvalidArgument());
|
||||
|
||||
@ -190,13 +187,8 @@ namespace ams::erpt::srv {
|
||||
if (m_initialized) {
|
||||
if (s_can_access_fs) {
|
||||
if (m_stream_mode == StreamMode_Write) {
|
||||
const auto self_flush_res = this->Flush();
|
||||
R_ASSERT(self_flush_res);
|
||||
AMS_UNUSED(self_flush_res);
|
||||
|
||||
const auto file_flush_res = fs::FlushFile(m_file_handle);
|
||||
R_ASSERT(file_flush_res);
|
||||
AMS_UNUSED(file_flush_res);
|
||||
this->Flush();
|
||||
fs::FlushFile(m_file_handle);
|
||||
}
|
||||
fs::CloseFile(m_file_handle);
|
||||
}
|
||||
|
||||
@ -585,7 +585,7 @@ namespace ams::fs::impl {
|
||||
}
|
||||
|
||||
/* Output. */
|
||||
static_cast<void>(OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1));
|
||||
OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,7 +593,7 @@ namespace ams::fs::impl {
|
||||
if ((g_global_access_log_mode & AccessLogMode_Log) != 0) {
|
||||
/* TODO: Support logging. */
|
||||
} else if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
|
||||
static_cast<void>(OutputAccessLogToSdCardImpl(log, size - 1));
|
||||
OutputAccessLogToSdCardImpl(log, size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -105,9 +105,7 @@ namespace ams::fs {
|
||||
AMS_ABORT_UNLESS(fsp_object != nullptr);
|
||||
|
||||
/* Set the current process. */
|
||||
const auto scp_res = fsp_object->SetCurrentProcess({});
|
||||
R_ASSERT(scp_res);
|
||||
AMS_UNUSED(scp_res);
|
||||
fsp_object->SetCurrentProcess({});
|
||||
}
|
||||
#else
|
||||
/* On non-horizon, use the system object. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user