mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-12-12 20:25:16 +01:00
Compare commits
64 Commits
1.9.0-prer
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21c0f75a29 | ||
|
|
3cb5d5f957 | ||
|
|
00d1cdb533 | ||
|
|
d9fc6e99eb | ||
|
|
c08a13a546 | ||
|
|
b5b6189c85 | ||
|
|
28a378ca0d | ||
|
|
540d00e097 | ||
|
|
bfe98bc5b8 | ||
|
|
4928bcb003 | ||
|
|
d61ee942d9 | ||
|
|
f59e6a936b | ||
|
|
129c61c256 | ||
|
|
db71eefd9f | ||
|
|
4b32a2b964 | ||
|
|
0fb9481e59 | ||
|
|
c05d91f44a | ||
|
|
e1d82a13f3 | ||
|
|
4f1201a022 | ||
|
|
4201bbff63 | ||
|
|
94c36a3255 | ||
|
|
6b0ef21b83 | ||
|
|
ac382f69e7 | ||
|
|
2a44550dbe | ||
|
|
3bc1951820 | ||
|
|
418fde40a8 | ||
|
|
e36051359c | ||
|
|
18bb1fdea0 | ||
|
|
c8e39a54d2 | ||
|
|
11a46e4579 | ||
|
|
652519da2e | ||
|
|
de9b02007b | ||
|
|
982f0e4fd4 | ||
|
|
d7936d3fa4 | ||
|
|
1c0ea680b6 | ||
|
|
b8ed942ae4 | ||
|
|
98bc030b37 | ||
|
|
081e76a2b5 | ||
|
|
e8de1e3c34 | ||
|
|
41b28bb0c4 | ||
|
|
3197b1e25b | ||
|
|
822cbbbc8b | ||
|
|
4237f52ee2 | ||
|
|
8b8e4438e8 | ||
|
|
debfff9f62 | ||
|
|
c77acb32be | ||
|
|
af859d9e65 | ||
|
|
a487efad6b | ||
|
|
7e0eb10e32 | ||
|
|
4a3e2b5c57 | ||
|
|
d8a37b4b71 | ||
|
|
b11850b3a3 | ||
|
|
77603bf7e5 | ||
|
|
6b01ebca9e | ||
|
|
17be65b4b9 | ||
|
|
409c3cf9e1 | ||
|
|
f4e1d0bf9f | ||
|
|
ae65b5df0c | ||
|
|
0a299a3d40 | ||
|
|
801438953d | ||
|
|
3fbc59cce1 | ||
|
|
f646d9c8f9 | ||
|
|
69cc653e7f | ||
|
|
6da88f8f3e |
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||

|

|
||||||
[](https://discordapp.com/invite/ZdqEhed)
|
[](https://discordapp.com/invite/ZdqEhed)
|
||||||
|

|
||||||
|
|
||||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
||||||
|
|
||||||
|
|||||||
@ -107,7 +107,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
|||||||
cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp
|
cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp
|
||||||
cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp
|
cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp
|
||||||
cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp
|
cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp
|
||||||
@build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs
|
@PATH="$(DEVKITPRO)/tools/bin:$$PATH" build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs
|
||||||
rm -r $(DIST_DIR)/stratosphere_romfs
|
rm -r $(DIST_DIR)/stratosphere_romfs
|
||||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro
|
cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro
|
||||||
cp troposphere/daybreak/daybreak.nro $(DIST_DIR)/switch/daybreak.nro
|
cp troposphere/daybreak/daybreak.nro $(DIST_DIR)/switch/daybreak.nro
|
||||||
@ -117,7 +117,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
|||||||
cp fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)/fusee.bin
|
cp fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)/fusee.bin
|
||||||
|
|
||||||
package3: emummc fusee stratosphere mesosphere exosphere troposphere
|
package3: emummc fusee stratosphere mesosphere exosphere troposphere
|
||||||
@python fusee/build_package3.py $(CURRENT_DIRECTORY) $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BOOT_OUT_DIR) $(ATMOSPHERE_GIT_HASH) $(ATMOSPHERE_MAJOR_VERSION) $(ATMOSPHERE_MINOR_VERSION) $(ATMOSPHERE_MICRO_VERSION) 0 $(ATMOSPHERE_SUPPORTED_HOS_MAJOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MINOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MICRO_VERSION) 0
|
$(SILENTCMD)$(PYTHON) fusee/build_package3.py $(CURRENT_DIRECTORY) $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BOOT_OUT_DIR) $(ATMOSPHERE_GIT_HASH) $(ATMOSPHERE_MAJOR_VERSION) $(ATMOSPHERE_MINOR_VERSION) $(ATMOSPHERE_MICRO_VERSION) 0 $(ATMOSPHERE_SUPPORTED_HOS_MAJOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MINOR_VERSION) $(ATMOSPHERE_SUPPORTED_HOS_MICRO_VERSION) 0
|
||||||
@echo "Built package3!"
|
@echo "Built package3!"
|
||||||
|
|
||||||
emummc:
|
emummc:
|
||||||
|
|||||||
@ -1,4 +1,49 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 1.10.0
|
||||||
|
+ Basic support was added for 21.0.0.
|
||||||
|
+ The console should boot and atmosphère should be fully functional.
|
||||||
|
+ **Please note**: All homebrew software may need to be re-compiled with the latest libnx (>= 4.10.0), or else it may crash/experience memory corruption.
|
||||||
|
+ Nintendo broke the userland<->kernel TLS ABI in 21.0.0, by writing to previously reserved space.
|
||||||
|
+ Homebrew used this reserved space for its TLS slots, which means any homebrew software using TLS slots will experience memory corruption when running under Atmosphere 1.10.0.
|
||||||
|
+ This doesn't appear to impact everything, but a large portion of tested homebrew crashes (often on exit), and so will need re-compile for the new ABI.
|
||||||
|
+ For those technically inclined, while TLS slots are rarely used by developers, they're used to implement features like e.g. C++ exceptions under the hood, and so anything using those crashes, etc.
|
||||||
|
+ To help make this transition easier, hbmenu now shows a warning when selecting homebrew compiled with an older, incompatible ABI version.
|
||||||
|
+ I apologize for the hassle in general.
|
||||||
|
+ libnx has been updated so that its reserved space matches Nintendo's now -- this particular issue can never occur again, even if Nintendo touches more reserved space.
|
||||||
|
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||||
|
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||||
|
+ `loader` was updated to reflect the latest official behavior.
|
||||||
|
+ `pm` was updated to reflect the latest official behavior.
|
||||||
|
+ `erpt` was updated to reflect the latest official behavior.
|
||||||
|
+ `pgl` was updated to reflect the latest official behavior.
|
||||||
|
+ `fatal` was updated to reflect the latest official behavior.
|
||||||
|
+ Support was added for launching another game-which-has-too-many-files with romfs mods.
|
||||||
|
+ I rely on user reports for adding support/fixing these, and some of these games can be pretty obscure!
|
||||||
|
+ If you are affected by this, you will see "Data abort (0x101)" when trying to launch the game with mods.
|
||||||
|
+ Please reach out to `sciresm` on discord if this occurs to share your error report binary.
|
||||||
|
+ Although some games may be impossible to fix, I believe I can get almost everything working, so please let me try to help you (and improve atmosphère's support!) if you run into this!
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.9.5
|
||||||
|
+ Basic support was added for 20.5.0.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.9.4
|
||||||
|
+ Basic support was added for 20.4.0.
|
||||||
|
+ An issue was fixed in `exosphère`'s register accessilibity tables (thanks @CTCaer).
|
||||||
|
+ I believe this had no impact on official code, though it would have prevented some homebrew from interacting correctly with the MC0/MC1 registers.
|
||||||
|
+ An issue was fixed that could cause a deadlock when building multiple romfs images simultaneously (thanks @Ereza).
|
||||||
|
+ This fixes support for certain mods, e.g. system language translations overriding content for both overlayDisp and qlaunch.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.9.3
|
||||||
|
+ Basic support was added for 20.3.0.
|
||||||
|
+ Compatibility was fixed for loading mods with KOTOR 2 (star wars).
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.9.2
|
||||||
|
+ Basic support was added for 20.2.0.
|
||||||
|
+ USB 3.0 support force-enable was fixed for 20.1.0+.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.9.1
|
||||||
|
+ Basic support was added for 20.1.0.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 1.9.0
|
## 1.9.0
|
||||||
+ Basic support was added for 20.0.0.
|
+ Basic support was added for 20.0.0.
|
||||||
+ The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes.
|
+ The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes.
|
||||||
|
|||||||
@ -423,41 +423,41 @@ Note that for multiple button combinations, the bitmasks should be OR'd together
|
|||||||
#### Keypad Values
|
#### Keypad Values
|
||||||
Note: This is the direct output of `hidKeysDown()`.
|
Note: This is the direct output of `hidKeysDown()`.
|
||||||
|
|
||||||
+ 000000001: A
|
+ 00000000 00000001: A
|
||||||
+ 000000002: B
|
+ 00000000 00000002: B
|
||||||
+ 000000004: X
|
+ 00000000 00000004: X
|
||||||
+ 000000008: Y
|
+ 00000000 00000008: Y
|
||||||
+ 000000010: Left Stick Pressed
|
+ 00000000 00000010: Left Stick Pressed
|
||||||
+ 000000020: Right Stick Pressed
|
+ 00000000 00000020: Right Stick Pressed
|
||||||
+ 000000040: L
|
+ 00000000 00000040: L
|
||||||
+ 000000080: R
|
+ 00000000 00000080: R
|
||||||
+ 000000100: ZL
|
+ 00000000 00000100: ZL
|
||||||
+ 000000200: ZR
|
+ 00000000 00000200: ZR
|
||||||
+ 000000400: Plus
|
+ 00000000 00000400: Plus
|
||||||
+ 000000800: Minus
|
+ 00000000 00000800: Minus
|
||||||
+ 000001000: Left
|
+ 00000000 00001000: Left
|
||||||
+ 000002000: Up
|
+ 00000000 00002000: Up
|
||||||
+ 000004000: Right
|
+ 00000000 00004000: Right
|
||||||
+ 000008000: Down
|
+ 00000000 00008000: Down
|
||||||
+ 000010000: Left Stick Left
|
+ 00000000 00010000: Left Stick Left
|
||||||
+ 000020000: Left Stick Up
|
+ 00000000 00020000: Left Stick Up
|
||||||
+ 000040000: Left Stick Right
|
+ 00000000 00040000: Left Stick Right
|
||||||
+ 000080000: Left Stick Down
|
+ 00000000 00080000: Left Stick Down
|
||||||
+ 000100000: Right Stick Left
|
+ 00000000 00100000: Right Stick Left
|
||||||
+ 000200000: Right Stick Up
|
+ 00000000 00200000: Right Stick Up
|
||||||
+ 000400000: Right Stick Right
|
+ 00000000 00400000: Right Stick Right
|
||||||
+ 000800000: Right Stick Down
|
+ 00000000 00800000: Right Stick Down
|
||||||
+ 001000000: SL Left Joy-Con
|
+ 00000000 01000000: SL Left Joy-Con
|
||||||
+ 002000000: SR Left Joy-Con
|
+ 00000000 02000000: SR Left Joy-Con
|
||||||
+ 004000000: SL Right Joy-Con
|
+ 00000000 04000000: SL Right Joy-Con
|
||||||
+ 008000000: SR Right Joy-Con
|
+ 00000000 08000000: SR Right Joy-Con
|
||||||
+ 010000000: Top button on Poké Ball Plus (Palma) controller
|
+ 00000000 10000000: Top button on Poké Ball Plus (Palma) controller
|
||||||
+ 020000000: Verification
|
+ 00000000 20000000: Verification
|
||||||
+ 040000000: B button on Left NES/HVC controller in Handheld mode
|
+ 00000000 40000000: B button on Left NES/HVC controller in Handheld mode
|
||||||
+ 080000000: Left C button in N64 controller
|
+ 00000000 80000000: Left C button in N64 controller
|
||||||
+ 100000000: Up C button in N64 controller
|
+ 00000001 00000000: Up C button in N64 controller
|
||||||
+ 200000000: Right C button in N64 controller
|
+ 00000002 00000000: Right C button in N64 controller
|
||||||
+ 400000000: Down C button in N64 controller
|
+ 00000004 00000000: Down C button in N64 controller
|
||||||
|
|
||||||
### Code Type 0xF0: Double Extended-Width Instruction
|
### Code Type 0xF0: Double Extended-Width Instruction
|
||||||
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.
|
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||||
|
|||||||
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emummc
|
remote = https://github.com/m4xw/emummc
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = 7522f1f6054a71bdff5beadee0302cead1235be3
|
commit = 3c57b20ba3820ec87d7dd239d6fcf9ba97510606
|
||||||
parent = 0e2ef545f947d24c6add254874ab493ba84bbdc9
|
parent = d61ee942d9b34cadd80464d5d549c5e2e5bf1689
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
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***
|
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||||
|
|
||||||
### Supported Horizon Versions
|
### Supported Horizon Versions
|
||||||
**1.0.0 - 20.0.0**
|
**1.0.0 - 21.0.0**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Arbitrary SDMMC backend selection
|
* Arbitrary SDMMC backend selection
|
||||||
|
|||||||
16
emummc/source/FS/FS_offsets.c
vendored
16
emummc/source/FS/FS_offsets.c
vendored
@ -77,6 +77,10 @@
|
|||||||
#include "offsets/1900_exfat.h"
|
#include "offsets/1900_exfat.h"
|
||||||
#include "offsets/2000.h"
|
#include "offsets/2000.h"
|
||||||
#include "offsets/2000_exfat.h"
|
#include "offsets/2000_exfat.h"
|
||||||
|
#include "offsets/2010.h"
|
||||||
|
#include "offsets/2010_exfat.h"
|
||||||
|
#include "offsets/2100.h"
|
||||||
|
#include "offsets/2100_exfat.h"
|
||||||
#include "../utils/fatal.h"
|
#include "../utils/fatal.h"
|
||||||
|
|
||||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||||
@ -165,6 +169,10 @@ DEFINE_OFFSET_STRUCT(_1900);
|
|||||||
DEFINE_OFFSET_STRUCT(_1900_EXFAT);
|
DEFINE_OFFSET_STRUCT(_1900_EXFAT);
|
||||||
DEFINE_OFFSET_STRUCT(_2000);
|
DEFINE_OFFSET_STRUCT(_2000);
|
||||||
DEFINE_OFFSET_STRUCT(_2000_EXFAT);
|
DEFINE_OFFSET_STRUCT(_2000_EXFAT);
|
||||||
|
DEFINE_OFFSET_STRUCT(_2010);
|
||||||
|
DEFINE_OFFSET_STRUCT(_2010_EXFAT);
|
||||||
|
DEFINE_OFFSET_STRUCT(_2100);
|
||||||
|
DEFINE_OFFSET_STRUCT(_2100_EXFAT);
|
||||||
|
|
||||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
@ -290,6 +298,14 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
|||||||
return &(GET_OFFSET_STRUCT_NAME(_2000));
|
return &(GET_OFFSET_STRUCT_NAME(_2000));
|
||||||
case FS_VER_20_0_0_EXFAT:
|
case FS_VER_20_0_0_EXFAT:
|
||||||
return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT));
|
return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT));
|
||||||
|
case FS_VER_20_1_0:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_2010));
|
||||||
|
case FS_VER_20_1_0_EXFAT:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT));
|
||||||
|
case FS_VER_21_0_0:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_2100));
|
||||||
|
case FS_VER_21_0_0_EXFAT:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_2100_EXFAT));
|
||||||
default:
|
default:
|
||||||
fatal_abort(Fatal_UnknownVersion);
|
fatal_abort(Fatal_UnknownVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
6
emummc/source/FS/FS_versions.h
vendored
6
emummc/source/FS/FS_versions.h
vendored
@ -113,6 +113,12 @@ enum FS_VER
|
|||||||
FS_VER_20_0_0,
|
FS_VER_20_0_0,
|
||||||
FS_VER_20_0_0_EXFAT,
|
FS_VER_20_0_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_20_1_0,
|
||||||
|
FS_VER_20_1_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_21_0_0,
|
||||||
|
FS_VER_21_0_0_EXFAT,
|
||||||
|
|
||||||
FS_VER_MAX,
|
FS_VER_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
59
emummc/source/FS/offsets/2010.h
vendored
Normal file
59
emummc/source/FS/offsets/2010.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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_2010_H__
|
||||||
|
#define __FS_2010_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_2010_SDMMC_ACCESSOR_GC 0x1A7DB0
|
||||||
|
#define FS_OFFSET_2010_SDMMC_ACCESSOR_SD 0x1AA130
|
||||||
|
#define FS_OFFSET_2010_SDMMC_ACCESSOR_NAND 0x1A8560
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_2010_SDMMC_WRAPPER_READ 0x1A3C20
|
||||||
|
#define FS_OFFSET_2010_SDMMC_WRAPPER_WRITE 0x1A3C80
|
||||||
|
#define FS_OFFSET_2010_RTLD 0x2B594
|
||||||
|
#define FS_OFFSET_2010_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
|
||||||
|
|
||||||
|
#define FS_OFFSET_2010_CLKRST_SET_MIN_V_CLK_RATE 0x1C6150
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_2010_LOCK_MUTEX 0x19CD80
|
||||||
|
#define FS_OFFSET_2010_UNLOCK_MUTEX 0x19CDD0
|
||||||
|
|
||||||
|
#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A3BE0
|
||||||
|
#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A3C00
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_2010_SD_MUTEX 0xFF5408
|
||||||
|
#define FS_OFFSET_2010_NAND_MUTEX 0xFF0CF0
|
||||||
|
#define FS_OFFSET_2010_ACTIVE_PARTITION 0xFF0D30
|
||||||
|
#define FS_OFFSET_2010_SDMMC_DAS_HANDLE 0xFD2B08
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_2010_SD_DAS_INIT 0x289F4
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_2010_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_2010_H__
|
||||||
59
emummc/source/FS/offsets/2010_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/2010_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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_2010_EXFAT_H__
|
||||||
|
#define __FS_2010_EXFAT_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_GC 0x1B36D0
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_SD 0x1B5A50
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_NAND 0x1B3E80
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_READ 0x1AF540
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_WRITE 0x1AF5A0
|
||||||
|
#define FS_OFFSET_2010_EXFAT_RTLD 0x2B594
|
||||||
|
#define FS_OFFSET_2010_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
|
||||||
|
|
||||||
|
#define FS_OFFSET_2010_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D1A70
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_2010_EXFAT_LOCK_MUTEX 0x1A86A0
|
||||||
|
#define FS_OFFSET_2010_EXFAT_UNLOCK_MUTEX 0x1A86F0
|
||||||
|
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF520
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SD_MUTEX 0x1006408
|
||||||
|
#define FS_OFFSET_2010_EXFAT_NAND_MUTEX 0x1001CF0
|
||||||
|
#define FS_OFFSET_2010_EXFAT_ACTIVE_PARTITION 0x1001D30
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SDMMC_DAS_HANDLE 0xFDFB08
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_2010_EXFAT_SD_DAS_INIT 0x289F4
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_2010_EXFAT_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_2010_EXFAT_H__
|
||||||
59
emummc/source/FS/offsets/2100.h
vendored
Normal file
59
emummc/source/FS/offsets/2100.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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
Normal file
59
emummc/source/FS/offsets/2100_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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__
|
||||||
@ -70,6 +70,6 @@ clean:
|
|||||||
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean
|
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean
|
||||||
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean ATMOSPHERE_CPU="$(strip $(ATMOSPHERE_BOOT_CPU))"
|
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/libexosphere.mk clean ATMOSPHERE_CPU="$(strip $(ATMOSPHERE_BOOT_CPU))"
|
||||||
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
||||||
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
|
||||||
|
|
||||||
.PHONY: all clean check_lib check_boot_lib check_loader_stub check_program check_mariko_fatal check_warmboot
|
.PHONY: all clean check_lib check_boot_lib check_loader_stub check_program check_mariko_fatal check_warmboot
|
||||||
@ -119,7 +119,7 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
$(OUTPUT).lz4 : $(OUTPUT).bin
|
$(OUTPUT).lz4 : $(OUTPUT).bin
|
||||||
@python $(CURRENT_DIRECTORY)/split_program.py $(OUTPUT).bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
$(SILENTCMD)$(PYTHON) $(CURRENT_DIRECTORY)/split_program.py $(OUTPUT).bin $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
||||||
@echo built ... $(notdir $@)
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
$(OUTPUT).bin : $(OUTPUT).elf
|
||||||
|
|||||||
@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
|||||||
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
||||||
/* TODO: Update on next change of keys. */
|
/* TODO: Update on next change of keys. */
|
||||||
/* Mariko Development Master Kek Source. */
|
/* Mariko Development Master Kek Source. */
|
||||||
.byte 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
|
.byte 0x11, 0x1C, 0x13, 0x90, 0xD9, 0x5E, 0xB0, 0xA2, 0xE3, 0xD0, 0x0E, 0x5D, 0xC4, 0xFB, 0x9E, 0xDB
|
||||||
|
|
||||||
/* Mariko Production Master Kek Source. */
|
/* Mariko Production Master Kek Source. */
|
||||||
.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
|
.byte 0xEB, 0xF3, 0x5B, 0x2D, 0x4A, 0x2D, 0xCE, 0x45, 0x3A, 0x6F, 0x61, 0x38, 0x0B, 0x00, 0x3B, 0x46
|
||||||
|
|
||||||
/* Development Master Key Vectors. */
|
/* Development Master Key Vectors. */
|
||||||
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
|
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
|
||||||
@ -111,6 +111,7 @@ _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 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */
|
||||||
.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */
|
.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */
|
||||||
.byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */
|
.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. */
|
/* Production Master Key Vectors. */
|
||||||
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
|
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
|
||||||
@ -133,6 +134,7 @@ _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 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */
|
||||||
.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */
|
.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */
|
||||||
.byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */
|
.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. */
|
/* Device Master Key Source Sources. */
|
||||||
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
|
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
|
||||||
@ -152,6 +154,7 @@ _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 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */
|
||||||
.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */
|
.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */
|
||||||
.byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */
|
.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. */
|
/* Development Device Master Kek Sources. */
|
||||||
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
|
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
|
||||||
@ -171,6 +174,7 @@ _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 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */
|
||||||
.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */
|
.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */
|
||||||
.byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */
|
.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. */
|
/* Production Device Master Kek Sources. */
|
||||||
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
|
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
|
||||||
@ -190,3 +194,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
|||||||
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
|
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
|
||||||
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
|
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
|
||||||
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
|
.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. */
|
||||||
@ -94,7 +94,7 @@ namespace ams::secmon::boot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the key generation is one that we can use. */
|
/* Check that the key generation is one that we can use. */
|
||||||
static_assert(pkg1::KeyGeneration_Count == 20);
|
static_assert(pkg1::KeyGeneration_Count == 21);
|
||||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,10 +101,10 @@ namespace ams::secmon::smc {
|
|||||||
#include "secmon_define_mc01_access_table.inc"
|
#include "secmon_define_mc01_access_table.inc"
|
||||||
|
|
||||||
constexpr const AccessTableEntry AccessTables[] = {
|
constexpr const AccessTableEntry AccessTables[] = {
|
||||||
{ PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
|
{ PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
|
||||||
{ McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
|
{ McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
|
||||||
{ Mc01AccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
|
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
|
||||||
{ Mc01AccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
|
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) {
|
constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) {
|
||||||
|
|||||||
@ -43,6 +43,6 @@ clean:
|
|||||||
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/loader_stub -f $(CURRENT_DIRECTORY)/loader_stub/loader_stub.mk clean
|
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/loader_stub -f $(CURRENT_DIRECTORY)/loader_stub/loader_stub.mk clean
|
||||||
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/program -f $(CURRENT_DIRECTORY)/program/program.mk clean
|
@$(MAKE) --no-print-directory -C $(CURRENT_DIRECTORY)/program -f $(CURRENT_DIRECTORY)/program/program.mk clean
|
||||||
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
@rm -fr $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR)
|
||||||
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
@for i in $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
|
||||||
|
|
||||||
.PHONY: all clean check_lib check_loader_stub check_program
|
.PHONY: all clean check_lib check_loader_stub check_program
|
||||||
@ -84,7 +84,7 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
$(OUTPUT).lz4 : $(OUTPUT).bin
|
$(OUTPUT).lz4 : $(OUTPUT).bin
|
||||||
@python $(CURRENT_DIRECTORY)/lz4_compress.py $(OUTPUT).bin $(OUTPUT).lz4
|
$(SILENTCMD)$(PYTHON) $(CURRENT_DIRECTORY)/lz4_compress.py $(OUTPUT).bin $(OUTPUT).lz4
|
||||||
@echo built ... $(notdir $@)
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
$(OUTPUT).bin : $(OUTPUT).elf
|
||||||
|
|||||||
@ -23,17 +23,17 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
|
||||||
/* TODO: Update on next change of keys. */
|
/* TODO: Update on next change of keys. */
|
||||||
0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A
|
0xEB, 0xF3, 0x5B, 0x2D, 0x4A, 0x2D, 0xCE, 0x45, 0x3A, 0x6F, 0x61, 0x38, 0x0B, 0x00, 0x3B, 0x46
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
||||||
/* TODO: Update on next change of keys. */
|
/* TODO: Update on next change of keys. */
|
||||||
0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03
|
0x11, 0x1C, 0x13, 0x90, 0xD9, 0x5E, 0xB0, 0xA2, 0xE3, 0xD0, 0x0E, 0x5D, 0xC4, 0xFB, 0x9E, 0xDB
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
|
||||||
/* TODO: Update on next change of keys. */
|
/* TODO: Update on next change of keys. */
|
||||||
0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8
|
0x66, 0xC8, 0xCB, 0x3D, 0xEC, 0xF4, 0x59, 0x73, 0x54, 0x88, 0xE1, 0x2E, 0xE6, 0x3D, 0x68, 0x46
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
|
||||||
@ -74,6 +74,7 @@ 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. */
|
{ 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */
|
||||||
{ 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */
|
{ 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */
|
||||||
{ 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */
|
{ 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] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||||
@ -94,6 +95,7 @@ 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. */
|
{ 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */
|
||||||
{ 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */
|
{ 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */
|
||||||
{ 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */
|
{ 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] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||||
@ -114,6 +116,7 @@ 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. */
|
{ 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */
|
||||||
{ 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */
|
{ 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */
|
||||||
{ 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */
|
{ 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] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||||
@ -137,6 +140,7 @@ 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. */
|
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */
|
||||||
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */
|
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */
|
||||||
{ 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */
|
{ 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] = {
|
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||||
@ -160,6 +164,7 @@ 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. */
|
{ 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */
|
||||||
{ 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */
|
{ 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */
|
||||||
{ 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */
|
{ 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] = {};
|
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};
|
||||||
|
|||||||
@ -80,7 +80,7 @@ namespace ams::nxboot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the key generation is one that we can use. */
|
/* Check that the key generation is one that we can use. */
|
||||||
static_assert(pkg1::KeyGeneration_Count == 20);
|
static_assert(pkg1::KeyGeneration_Count == 21);
|
||||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -265,6 +265,8 @@ namespace ams::nxboot {
|
|||||||
return ams::TargetFirmware_19_0_0;
|
return ams::TargetFirmware_19_0_0;
|
||||||
} else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) {
|
} else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) {
|
||||||
return ams::TargetFirmware_20_0_0;
|
return ams::TargetFirmware_20_0_0;
|
||||||
|
} else if (std::memcmp(package1 + 0x10, "20251009", 8) == 0) {
|
||||||
|
return ams::TargetFirmware_21_0_0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -409,8 +411,9 @@ namespace ams::nxboot {
|
|||||||
/* If we should, save the current warmboot firmware. */
|
/* If we should, save the current warmboot firmware. */
|
||||||
UpdateWarmbootPath(expected_fuses);
|
UpdateWarmbootPath(expected_fuses);
|
||||||
if (!IsFileExist(warmboot_path)) {
|
if (!IsFileExist(warmboot_path)) {
|
||||||
fs::CreateDirectory("sdmc:/warmboot_mariko");
|
/* Try to create the directory/file, allowing them to fail (if already exist). */
|
||||||
fs::CreateFile(warmboot_path, warmboot_src_size);
|
static_cast<void>(fs::CreateDirectory("sdmc:/warmboot_mariko"));
|
||||||
|
static_cast<void>(fs::CreateFile(warmboot_path, warmboot_src_size));
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
|
|||||||
@ -183,6 +183,12 @@ namespace ams::nxboot {
|
|||||||
FsVersion_20_0_0,
|
FsVersion_20_0_0,
|
||||||
FsVersion_20_0_0_Exfat,
|
FsVersion_20_0_0_Exfat,
|
||||||
|
|
||||||
|
FsVersion_20_1_0,
|
||||||
|
FsVersion_20_1_0_Exfat,
|
||||||
|
|
||||||
|
FsVersion_21_0_0,
|
||||||
|
FsVersion_21_0_0_Exfat,
|
||||||
|
|
||||||
FsVersion_Count,
|
FsVersion_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -278,6 +284,12 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
{ 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */
|
{ 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */
|
||||||
{ 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */
|
{ 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */
|
||||||
|
|
||||||
|
{ 0xED, 0x34, 0xB4, 0x50, 0x58, 0x4A, 0x5B, 0x43 }, /* FsVersion_20_1_0 */
|
||||||
|
{ 0xA5, 0x1A, 0xA4, 0x92, 0x6C, 0x41, 0x87, 0x59 }, /* FsVersion_20_1_0_Exfat */
|
||||||
|
|
||||||
|
{ 0xEE, 0x4B, 0x30, 0x12, 0xA6, 0x84, 0x02, 0x25 }, /* FsVersion_21_0_0 */
|
||||||
|
{ 0x6E, 0x2B, 0xD9, 0xBA, 0xA3, 0xB9, 0x10, 0xF1 }, /* FsVersion_21_0_0_Exfat */
|
||||||
};
|
};
|
||||||
|
|
||||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||||
@ -668,15 +680,27 @@ namespace ams::nxboot {
|
|||||||
AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1));
|
AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1));
|
||||||
break;
|
break;
|
||||||
case FsVersion_20_0_0:
|
case FsVersion_20_0_0:
|
||||||
|
case FsVersion_20_1_0:
|
||||||
AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0));
|
AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0));
|
||||||
AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0));
|
AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0));
|
||||||
AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1));
|
AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1));
|
||||||
break;
|
break;
|
||||||
case FsVersion_20_0_0_Exfat:
|
case FsVersion_20_0_0_Exfat:
|
||||||
|
case FsVersion_20_1_0_Exfat:
|
||||||
AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0));
|
AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0));
|
||||||
AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0));
|
AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0));
|
||||||
AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1));
|
AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1));
|
||||||
break;
|
break;
|
||||||
|
case FsVersion_21_0_0:
|
||||||
|
AddPatch(fs_meta, 0x1AC9ED, NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x1ACA05 , NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x17FBE0, NogcPatch1, sizeof(NogcPatch1));
|
||||||
|
break;
|
||||||
|
case FsVersion_21_0_0_Exfat:
|
||||||
|
AddPatch(fs_meta, 0x1B7B4D, NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x1B7B65, NogcPatch0, sizeof(NogcPatch0));
|
||||||
|
AddPatch(fs_meta, 0x18AD40, NogcPatch1, sizeof(NogcPatch1));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
img/np++.png
Normal file
BIN
img/np++.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 9e8cbe3faa4604e9ae162546d13a74755ce30667
|
commit = 6cc765fcaa5f83b9cd6dc5b424bae31a0f33b29f
|
||||||
parent = 4d4f0ba96876d20e505c7aa11c9bf215f276dd8b
|
parent = 3cb5d5f957020d07f5bdb3fb89521f29bea5d79d
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@ -297,6 +297,23 @@ FIND_SOURCE_FILES=$(foreach dir,$1,$(filter-out $(notdir $(wildcard $(dir)/*.arc
|
|||||||
|
|
||||||
ATMOSPHERE_GCH_IDENTIFIER := $(ATMOSPHERE_FULL_NAME)
|
ATMOSPHERE_GCH_IDENTIFIER := $(ATMOSPHERE_FULL_NAME)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Python. The scripts should work with Python 2 or 3, but 2 is preferred.
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
PYTHON = $(shell command -v python >/dev/null && echo python || echo python3)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Export MAKE:
|
||||||
|
# GCC's LTO driver invokes Make internally. This invocation respects both $(MAKE)
|
||||||
|
# and $(MAKEFLAGS), but only if they're in the environment. By default, MAKEFLAGS
|
||||||
|
# is in the environment while MAKE isn't, so GCC will always use the default
|
||||||
|
# `make` command, yet it inherits MAKEFLAGS from the copy of Make the user
|
||||||
|
# invoked, which might have incompatible flags. In practice this is an issue on
|
||||||
|
# macOS when running e.g. `gmake -j32 -Otarget`. This behavior is arguably a bug
|
||||||
|
# in GCC and/or Make, but we can work around it by exporting MAKE.
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export MAKE
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# Rules for compiling pre-compiled headers
|
# Rules for compiling pre-compiled headers
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -26,7 +26,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
export DEFINES = $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
export DEFINES = $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
||||||
export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers
|
export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -Wno-error=unused-result
|
||||||
export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
|
export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
|
||||||
export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
|
export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
|
||||||
|
|||||||
@ -40,6 +40,7 @@ namespace ams::pkg1 {
|
|||||||
KeyGeneration_18_0_0 = 0x11,
|
KeyGeneration_18_0_0 = 0x11,
|
||||||
KeyGeneration_19_0_0 = 0x12,
|
KeyGeneration_19_0_0 = 0x12,
|
||||||
KeyGeneration_20_0_0 = 0x13,
|
KeyGeneration_20_0_0 = 0x13,
|
||||||
|
KeyGeneration_21_0_0 = 0x14,
|
||||||
|
|
||||||
KeyGeneration_Count,
|
KeyGeneration_Count,
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace ams::pkg2 {
|
|||||||
constexpr inline int PayloadCount = 3;
|
constexpr inline int PayloadCount = 3;
|
||||||
|
|
||||||
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */
|
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */
|
||||||
constexpr inline int CurrentBootloaderVersion = 0x17;
|
constexpr inline int CurrentBootloaderVersion = 0x18;
|
||||||
|
|
||||||
struct Package2Meta {
|
struct Package2Meta {
|
||||||
using Magic = util::FourCC<'P','K','2','1'>;
|
using Magic = util::FourCC<'P','K','2','1'>;
|
||||||
|
|||||||
@ -104,7 +104,7 @@ clean:
|
|||||||
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
||||||
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
||||||
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
||||||
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@ -177,6 +177,7 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
|
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
|
||||||
|
TargetFirmware_21_0_0,
|
||||||
TargetFirmware_20_0_0,
|
TargetFirmware_20_0_0,
|
||||||
TargetFirmware_19_0_0,
|
TargetFirmware_19_0_0,
|
||||||
TargetFirmware_17_0_0,
|
TargetFirmware_17_0_0,
|
||||||
|
|||||||
@ -116,7 +116,9 @@ namespace ams::kern::arch::arm {
|
|||||||
u32 ipriorityr[NumLocalInterrupts / 4];
|
u32 ipriorityr[NumLocalInterrupts / 4];
|
||||||
u32 itargetsr[NumLocalInterrupts / 4];
|
u32 itargetsr[NumLocalInterrupts / 4];
|
||||||
u32 icfgr[NumLocalInterrupts / 16];
|
u32 icfgr[NumLocalInterrupts / 16];
|
||||||
|
u32 spendsgir[4];
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(LocalState{}.spendsgir) == sizeof(GicDistributor{}.spendsgir));
|
||||||
|
|
||||||
struct GlobalState {
|
struct GlobalState {
|
||||||
u32 isenabler[NumGlobalInterrupts / 32];
|
u32 isenabler[NumGlobalInterrupts / 32];
|
||||||
|
|||||||
@ -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 Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
|
||||||
NOINLINE Result UnbindHandler(s32 irq, s32 core);
|
NOINLINE void UnbindHandler(s32 irq, s32 core);
|
||||||
|
|
||||||
NOINLINE Result ClearInterrupt(s32 irq, s32 core_id);
|
NOINLINE void ClearInterrupt(s32 irq, s32 core_id);
|
||||||
|
|
||||||
ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
|
ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
|
||||||
m_interrupt_controller.SendInterProcessorInterrupt(irq, core_mask);
|
m_interrupt_controller.SendInterProcessorInterrupt(irq, core_mask);
|
||||||
@ -99,10 +99,10 @@ namespace ams::kern::arch::arm64 {
|
|||||||
private:
|
private:
|
||||||
Result BindGlobal(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
|
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);
|
Result BindLocal(KInterruptHandler *handler, s32 irq, s32 priority, bool manual_clear);
|
||||||
Result UnbindGlobal(s32 irq);
|
void UnbindGlobal(s32 irq);
|
||||||
Result UnbindLocal(s32 irq);
|
void UnbindLocal(s32 irq);
|
||||||
Result ClearGlobal(s32 irq);
|
void ClearGlobal(s32 irq);
|
||||||
Result ClearLocal(s32 irq);
|
void ClearLocal(s32 irq);
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() {
|
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() {
|
||||||
u64 intr_state;
|
u64 intr_state;
|
||||||
|
|||||||
@ -197,9 +197,9 @@ namespace ams::kern::arch::arm64 {
|
|||||||
cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id);
|
cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
|
NOINLINE void InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
|
||||||
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index);
|
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index);
|
||||||
Result Finalize();
|
void Finalize();
|
||||||
|
|
||||||
static void NoteUpdatedCallback(const void *pt) {
|
static void NoteUpdatedCallback(const void *pt) {
|
||||||
/* Note the update. */
|
/* 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() { /* ... */ }
|
constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_fpcr(), m_fpsr(), m_callee_saved_fpu(), m_locked() { /* ... */ }
|
||||||
explicit KThreadContext() { /* ... */ }
|
explicit KThreadContext() { /* ... */ }
|
||||||
|
|
||||||
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 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);
|
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 CopyMemoryToUser(void *dst, const void *src, size_t size);
|
||||||
static bool CopyMemoryToUserAligned32Bit(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 CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size);
|
||||||
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src);
|
static bool CopyMemoryToUserSize32Bit(void *dst, u32 value);
|
||||||
static s32 CopyStringToUser(void *dst, const void *src, size_t size);
|
static s32 CopyStringToUser(void *dst, const void *src, size_t size);
|
||||||
|
|
||||||
static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask);
|
static bool 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);
|
return Impl::CopyMemoryToUserAligned64Bit(dst, src, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CopyMemoryToUserSize32Bit(void *dst, const void *src) {
|
static bool CopyMemoryToUserSize32Bit(void *dst, u32 value) {
|
||||||
return Impl::CopyMemoryToUserSize32Bit(dst, src);
|
return Impl::CopyMemoryToUserSize32Bit(dst, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 CopyStringToUser(void *dst, const void *src, size_t size) {
|
static s32 CopyStringToUser(void *dst, const void *src, size_t size) {
|
||||||
|
|||||||
@ -47,13 +47,6 @@
|
|||||||
/* re-enabled by toggling this define. */
|
/* re-enabled by toggling this define. */
|
||||||
//#define MESOSPHERE_ENABLE_PROCESS_CREATION_TIME
|
//#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 */
|
/* NOTE: This enables usage of KDebug handles as parameter for svc::GetInfo */
|
||||||
/* calls which require a process parameter. This enables a debugger to obtain */
|
/* calls which require a process parameter. This enables a debugger to obtain */
|
||||||
/* address space/layout information, for example. However, it changes abi, and so */
|
/* address space/layout information, for example. However, it changes abi, and so */
|
||||||
|
|||||||
@ -121,14 +121,9 @@ namespace ams::kern {
|
|||||||
private:
|
private:
|
||||||
KAutoObject *m_next_closed_object;
|
KAutoObject *m_next_closed_object;
|
||||||
ReferenceCount m_ref_count;
|
ReferenceCount m_ref_count;
|
||||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
|
||||||
ClassTokenType m_class_token;
|
ClassTokenType m_class_token;
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0)
|
constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0), m_class_token(0)
|
||||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
|
||||||
, m_class_token(0)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
}
|
}
|
||||||
@ -151,19 +146,11 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsDerivedFrom(const TypeObj &rhs) const {
|
ALWAYS_INLINE bool IsDerivedFrom(const TypeObj &rhs) const {
|
||||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.GetClassToken());
|
||||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.GetClassToken());
|
|
||||||
#else
|
|
||||||
return this->GetTypeObj().IsDerivedFrom(rhs);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsDerivedFrom(const KAutoObject &rhs) const {
|
ALWAYS_INLINE bool IsDerivedFrom(const KAutoObject &rhs) const {
|
||||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.m_class_token);
|
||||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.m_class_token);
|
|
||||||
#else
|
|
||||||
return this->IsDerivedFrom(rhs.GetTypeObj());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@ -218,12 +205,10 @@ namespace ams::kern {
|
|||||||
KAutoObject &auto_object = *static_cast<KAutoObject *>(obj);
|
KAutoObject &auto_object = *static_cast<KAutoObject *>(obj);
|
||||||
|
|
||||||
/* If we should, set our class token. */
|
/* If we should, set our class token. */
|
||||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
|
||||||
{
|
{
|
||||||
constexpr auto Token = Derived::GetStaticTypeObj().GetClassToken();
|
constexpr auto Token = Derived::GetStaticTypeObj().GetClassToken();
|
||||||
auto_object.m_class_token = Token;
|
auto_object.m_class_token = Token;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize reference count to 1. */
|
/* Initialize reference count to 1. */
|
||||||
auto_object.m_ref_count = 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);
|
static Result ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
|
||||||
public:
|
public:
|
||||||
static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
|
static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
|
||||||
static Result OnExitProcess(KProcess *process);
|
static void OnExitProcess(KProcess *process);
|
||||||
static Result OnTerminateProcess(KProcess *process);
|
static void OnTerminateProcess(KProcess *process);
|
||||||
static Result OnExitThread(KThread *thread);
|
static void OnExitThread(KThread *thread);
|
||||||
static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, u64 thread_id, const uintptr_t *params, size_t num_params);
|
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; }
|
KReadableEvent &GetReadableEvent() { return m_readable_event; }
|
||||||
|
|
||||||
Result Signal();
|
void Signal();
|
||||||
Result Clear();
|
void Clear();
|
||||||
|
|
||||||
ALWAYS_INLINE void OnReadableEventDestroyed() { m_readable_event_destroyed = true; }
|
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 GetCount() const { return m_count; }
|
||||||
constexpr ALWAYS_INLINE size_t GetMaxCount() const { return m_max_count; }
|
constexpr ALWAYS_INLINE size_t GetMaxCount() const { return m_max_count; }
|
||||||
|
|
||||||
MESOSPHERE_NOINLINE_IF_DEBUG Result Finalize();
|
MESOSPHERE_NOINLINE_IF_DEBUG void Finalize();
|
||||||
MESOSPHERE_NOINLINE_IF_DEBUG bool Remove(ams::svc::Handle handle);
|
MESOSPHERE_NOINLINE_IF_DEBUG bool Remove(ams::svc::Handle handle);
|
||||||
|
|
||||||
template<typename T = KAutoObject>
|
template<typename T = KAutoObject>
|
||||||
|
|||||||
@ -38,13 +38,11 @@ namespace ams::kern {
|
|||||||
|
|
||||||
Result Reset();
|
Result Reset();
|
||||||
|
|
||||||
Result Clear() {
|
void Clear() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
/* Try to perform a reset, succeeding unconditionally. */
|
/* Try to perform a reset, ignoring whether it succeeds. */
|
||||||
this->Reset();
|
static_cast<void>(this->Reset());
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInitialized() const { return m_is_initialized; }
|
bool IsInitialized() const { return m_is_initialized; }
|
||||||
|
|||||||
@ -226,7 +226,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
explicit KPageTableBase() { /* ... */ }
|
explicit KPageTableBase() { /* ... */ }
|
||||||
|
|
||||||
NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
|
NOINLINE void 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);
|
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();
|
void Finalize();
|
||||||
|
|||||||
@ -269,7 +269,7 @@ namespace ams::kern {
|
|||||||
void RemoveIoRegion(KIoRegion *io_region);
|
void RemoveIoRegion(KIoRegion *io_region);
|
||||||
|
|
||||||
Result CreateThreadLocalRegion(KProcessAddress *out);
|
Result CreateThreadLocalRegion(KProcessAddress *out);
|
||||||
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
void DeleteThreadLocalRegion(KProcessAddress addr);
|
||||||
void *GetThreadLocalRegionPointer(KProcessAddress addr);
|
void *GetThreadLocalRegionPointer(KProcessAddress addr);
|
||||||
|
|
||||||
constexpr KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; }
|
constexpr KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; }
|
||||||
|
|||||||
@ -35,16 +35,14 @@ namespace ams::kern {
|
|||||||
|
|
||||||
constexpr KEvent *GetParent() const { return m_parent; }
|
constexpr KEvent *GetParent() const { return m_parent; }
|
||||||
|
|
||||||
Result Signal();
|
void Signal();
|
||||||
Result Reset();
|
Result Reset();
|
||||||
|
|
||||||
Result Clear() {
|
void Clear() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
/* Try to perform a reset, succeeding unconditionally. */
|
/* Try to perform a reset, ignoring whether it succeeds. */
|
||||||
this->Reset();
|
static_cast<void>(this->Reset());
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|||||||
@ -105,7 +105,7 @@ namespace ams::kern {
|
|||||||
util::Atomic<u8> dpc_flags;
|
util::Atomic<u8> dpc_flags;
|
||||||
u8 current_svc_id;
|
u8 current_svc_id;
|
||||||
u8 reserved_2c;
|
u8 reserved_2c;
|
||||||
u8 exception_flags;
|
util::Atomic<u8> exception_flags;
|
||||||
bool is_pinned;
|
bool is_pinned;
|
||||||
u8 reserved_2f;
|
u8 reserved_2f;
|
||||||
u8 reserved_30[0x10];
|
u8 reserved_30[0x10];
|
||||||
@ -417,17 +417,17 @@ namespace ams::kern {
|
|||||||
private:
|
private:
|
||||||
ALWAYS_INLINE void SetExceptionFlag(ExceptionFlag flag) {
|
ALWAYS_INLINE void SetExceptionFlag(ExceptionFlag flag) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
this->GetStackParameters().exception_flags |= flag;
|
this->GetStackParameters().exception_flags.FetchOr<std::memory_order_relaxed>(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void ClearExceptionFlag(ExceptionFlag flag) {
|
ALWAYS_INLINE void ClearExceptionFlag(ExceptionFlag flag) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
this->GetStackParameters().exception_flags &= ~flag;
|
this->GetStackParameters().exception_flags.FetchAnd<std::memory_order_relaxed>(~flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsExceptionFlagSet(ExceptionFlag flag) const {
|
ALWAYS_INLINE bool IsExceptionFlagSet(ExceptionFlag flag) const {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
return this->GetStackParameters().exception_flags & flag;
|
return this->GetStackParameters().exception_flags.Load<std::memory_order_relaxed>() & flag;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/* ALWAYS_INLINE void SetCallingSvc() { return this->SetExceptionFlag(ExceptionFlag_IsCallingSvc); } */
|
/* 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 GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
|
||||||
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
|
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
|
||||||
|
|
||||||
Result GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
|
void 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 GetState() const { return static_cast<ThreadState>(m_thread_state & ThreadState_Mask); }
|
||||||
constexpr ThreadState GetRawState() const { return m_thread_state; }
|
constexpr ThreadState GetRawState() const { return m_thread_state; }
|
||||||
@ -717,7 +717,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetBasePriority(s32 priority);
|
void SetBasePriority(s32 priority);
|
||||||
Result SetPriorityToIdle();
|
void SetPriorityToIdle();
|
||||||
|
|
||||||
Result Run();
|
Result Run();
|
||||||
void Exit();
|
void Exit();
|
||||||
@ -725,7 +725,7 @@ namespace ams::kern {
|
|||||||
Result Terminate();
|
Result Terminate();
|
||||||
ThreadState RequestTerminate();
|
ThreadState RequestTerminate();
|
||||||
|
|
||||||
Result Sleep(s64 timeout);
|
void Sleep(s64 timeout);
|
||||||
|
|
||||||
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(m_kernel_stack_top) - 1; }
|
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(m_kernel_stack_top) - 1; }
|
||||||
ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; }
|
ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; }
|
||||||
|
|||||||
@ -77,7 +77,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
Result Initialize(KProcess *process);
|
Result Initialize(KProcess *process);
|
||||||
Result Finalize();
|
void Finalize();
|
||||||
|
|
||||||
KProcessAddress Reserve();
|
KProcessAddress Reserve();
|
||||||
void Release(KProcessAddress addr);
|
void Release(KProcessAddress addr);
|
||||||
|
|||||||
@ -86,7 +86,7 @@ clean:
|
|||||||
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
||||||
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
||||||
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
||||||
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@ -113,6 +113,11 @@ namespace ams::kern::arch::arm {
|
|||||||
constexpr size_t Offset = 0;
|
constexpr size_t Offset = 0;
|
||||||
state->icfgr[i] = m_gicd->icfgr[i + Offset];
|
state->icfgr[i] = m_gicd->icfgr[i + Offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save spendsgir. */
|
||||||
|
for (size_t i = 0; i < util::size(state->spendsgir); ++i) {
|
||||||
|
state->spendsgir[i] = m_gicd->spendsgir[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KInterruptController::SaveGlobal(GlobalState *state) const {
|
void KInterruptController::SaveGlobal(GlobalState *state) const {
|
||||||
@ -168,6 +173,11 @@ namespace ams::kern::arch::arm {
|
|||||||
m_gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
m_gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
||||||
m_gicd->isenabler[i + Offset] = state->isenabler[i];
|
m_gicd->isenabler[i + Offset] = state->isenabler[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore spendsgir. */
|
||||||
|
for (size_t i = 0; i < util::size(state->spendsgir); ++i) {
|
||||||
|
m_gicd->spendsgir[i] = state->spendsgir[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KInterruptController::RestoreGlobal(const GlobalState *state) const {
|
void KInterruptController::RestoreGlobal(const GlobalState *state) const {
|
||||||
|
|||||||
@ -112,7 +112,7 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
class KCoreBarrierInterruptHandler : public KInterruptHandler {
|
class KCoreBarrierInterruptHandler : public KInterruptHandler {
|
||||||
private:
|
private:
|
||||||
util::Atomic<u64> m_target_cores;
|
util::Atomic<u64> m_target_cores;
|
||||||
KSpinLock m_lock;
|
KLightLock m_lock;
|
||||||
public:
|
public:
|
||||||
constexpr KCoreBarrierInterruptHandler() : KInterruptHandler(), m_target_cores(0), m_lock() { /* ... */ }
|
constexpr KCoreBarrierInterruptHandler() : KInterruptHandler(), m_target_cores(0), m_lock() { /* ... */ }
|
||||||
|
|
||||||
@ -123,11 +123,8 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SynchronizeCores(u64 core_mask) {
|
void SynchronizeCores(u64 core_mask) {
|
||||||
/* Disable dispatch while we synchronize. */
|
|
||||||
KScopedDisableDispatch dd;
|
|
||||||
|
|
||||||
/* Acquire exclusive access to ourselves. */
|
/* Acquire exclusive access to ourselves. */
|
||||||
KScopedSpinLock lk(m_lock);
|
KScopedLightLock lk(m_lock);
|
||||||
|
|
||||||
/* If necessary, force synchronization with other cores. */
|
/* If necessary, force synchronization with other cores. */
|
||||||
if (const u64 other_cores_mask = core_mask & ~(1ul << GetCurrentCoreId()); other_cores_mask != 0) {
|
if (const u64 other_cores_mask = core_mask & ~(1ul << GetCurrentCoreId()); other_cores_mask != 0) {
|
||||||
@ -218,7 +215,7 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
KThread::Register(new_thread);
|
KThread::Register(new_thread);
|
||||||
|
|
||||||
/* Run the thread. */
|
/* Run the thread. */
|
||||||
new_thread->Run();
|
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
|
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
|
||||||
@ -511,16 +508,16 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
g_cache_operation_handler.Initialize(core_id);
|
g_cache_operation_handler.Initialize(core_id);
|
||||||
|
|
||||||
/* Bind all handlers to the relevant interrupts. */
|
/* Bind all handlers to the relevant interrupts. */
|
||||||
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_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);
|
MESOSPHERE_R_ABORT_UNLESS(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);
|
MESOSPHERE_R_ABORT_UNLESS(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 we should, enable user access to the performance counter registers. */
|
||||||
if (KTargetSystem::IsUserPmuAccessEnabled()) { SetPmUserEnrEl0(1ul); }
|
if (KTargetSystem::IsUserPmuAccessEnabled()) { SetPmUserEnrEl0(1ul); }
|
||||||
|
|
||||||
/* If we should, enable the kernel performance counter interrupt handler. */
|
/* If we should, enable the kernel performance counter interrupt handler. */
|
||||||
#if defined(MESOSPHERE_ENABLE_PERFORMANCE_COUNTER)
|
#if defined(MESOSPHERE_ENABLE_PERFORMANCE_COUNTER)
|
||||||
Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false);
|
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false));
|
||||||
#endif
|
#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()));
|
m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue()));
|
||||||
|
|
||||||
/* Bind the interrupt task for this core. */
|
/* Bind the interrupt task for this core. */
|
||||||
Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true);
|
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KHardwareTimer::Finalize() {
|
void KHardwareTimer::Finalize() {
|
||||||
|
|||||||
@ -126,7 +126,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
if (entry.handler != nullptr) {
|
if (entry.handler != nullptr) {
|
||||||
/* Set manual clear needed if relevant. */
|
/* Set manual clear needed if relevant. */
|
||||||
if (entry.manually_cleared) {
|
if (entry.manually_cleared) {
|
||||||
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
m_interrupt_controller.Disable(irq);
|
||||||
entry.needs_clear = true;
|
entry.needs_clear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,40 +242,40 @@ namespace ams::kern::arch::arm64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
|
void KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
|
||||||
MESOSPHERE_UNUSED(core_id);
|
MESOSPHERE_UNUSED(core_id);
|
||||||
|
|
||||||
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
|
||||||
|
|
||||||
|
|
||||||
if (KInterruptController::IsGlobal(irq)) {
|
if (KInterruptController::IsGlobal(irq)) {
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
||||||
R_RETURN(this->UnbindGlobal(irq));
|
return this->UnbindGlobal(irq);
|
||||||
} else {
|
} else if (KInterruptController::IsLocal(irq)) {
|
||||||
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
||||||
|
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
R_RETURN(this->UnbindLocal(irq));
|
return this->UnbindLocal(irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
|
void KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
|
||||||
MESOSPHERE_UNUSED(core_id);
|
MESOSPHERE_UNUSED(core_id);
|
||||||
|
|
||||||
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
|
||||||
|
|
||||||
|
|
||||||
if (KInterruptController::IsGlobal(irq)) {
|
if (KInterruptController::IsGlobal(irq)) {
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
||||||
R_RETURN(this->ClearGlobal(irq));
|
return this->ClearGlobal(irq);
|
||||||
} else {
|
} else if (KInterruptController::IsLocal(irq)) {
|
||||||
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
||||||
|
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
R_RETURN(this->ClearLocal(irq));
|
return this->ClearLocal(irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +332,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::UnbindGlobal(s32 irq) {
|
void KInterruptManager::UnbindGlobal(s32 irq) {
|
||||||
for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) {
|
for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) {
|
||||||
m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
|
m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
|
||||||
}
|
}
|
||||||
@ -340,50 +340,35 @@ namespace ams::kern::arch::arm64 {
|
|||||||
m_interrupt_controller.Disable(irq);
|
m_interrupt_controller.Disable(irq);
|
||||||
|
|
||||||
GetGlobalInterruptEntry(irq).handler = nullptr;
|
GetGlobalInterruptEntry(irq).handler = nullptr;
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::UnbindLocal(s32 irq) {
|
void 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.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||||
m_interrupt_controller.Disable(irq);
|
m_interrupt_controller.Disable(irq);
|
||||||
|
|
||||||
entry.handler = nullptr;
|
this->GetLocalInterruptEntry(irq).handler = nullptr;
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::ClearGlobal(s32 irq) {
|
void KInterruptManager::ClearGlobal(s32 irq) {
|
||||||
/* We can't clear an entry with no handler. */
|
/* Get the entry. */
|
||||||
auto &entry = GetGlobalInterruptEntry(irq);
|
auto &entry = GetGlobalInterruptEntry(irq);
|
||||||
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
|
|
||||||
|
|
||||||
/* If auto-cleared, we can succeed immediately. */
|
/* If not auto-cleared, clear and enable. */
|
||||||
R_SUCCEED_IF(!entry.manually_cleared);
|
if (entry.manually_cleared && entry.needs_clear) {
|
||||||
R_SUCCEED_IF(!entry.needs_clear);
|
entry.needs_clear = false;
|
||||||
|
m_interrupt_controller.Enable(irq);
|
||||||
/* Clear and enable. */
|
}
|
||||||
entry.needs_clear = false;
|
|
||||||
m_interrupt_controller.Enable(irq);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KInterruptManager::ClearLocal(s32 irq) {
|
void KInterruptManager::ClearLocal(s32 irq) {
|
||||||
/* We can't clear an entry with no handler. */
|
/* Get the entry. */
|
||||||
auto &entry = this->GetLocalInterruptEntry(irq);
|
auto &entry = this->GetLocalInterruptEntry(irq);
|
||||||
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
|
|
||||||
|
|
||||||
/* If auto-cleared, we can succeed immediately. */
|
/* If not auto-cleared, clear and enable. */
|
||||||
R_SUCCEED_IF(!entry.manually_cleared);
|
if (entry.manually_cleared && entry.needs_clear) {
|
||||||
R_SUCCEED_IF(!entry.needs_clear);
|
entry.needs_clear = false;
|
||||||
|
m_interrupt_controller.Enable(irq);
|
||||||
/* Clear and set priority. */
|
}
|
||||||
entry.needs_clear = false;
|
|
||||||
m_interrupt_controller.SetPriorityLevel(irq, entry.priority);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,15 +119,13 @@ namespace ams::kern::arch::arm64 {
|
|||||||
MESOSPHERE_UNUSED(core_id);
|
MESOSPHERE_UNUSED(core_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
|
void KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
|
||||||
/* Initialize basic fields. */
|
/* Initialize basic fields. */
|
||||||
m_asid = 0;
|
m_asid = 0;
|
||||||
m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer();
|
m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer();
|
||||||
|
|
||||||
/* Initialize the base page table. */
|
/* Initialize the base page table. */
|
||||||
MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end));
|
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) {
|
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) {
|
||||||
@ -153,7 +151,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTable::Finalize() {
|
void KPageTable::Finalize() {
|
||||||
/* Only process tables should be finalized. */
|
/* Only process tables should be finalized. */
|
||||||
MESOSPHERE_ASSERT(!this->IsKernel());
|
MESOSPHERE_ASSERT(!this->IsKernel());
|
||||||
|
|
||||||
@ -271,8 +269,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
/* Perform inherited finalization. */
|
/* Perform inherited finalization. */
|
||||||
KPageTableBase::Finalize();
|
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) {
|
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) {
|
||||||
@ -942,7 +938,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
/* If we should flush entries, do so. */
|
/* If we should flush entries, do so. */
|
||||||
if ((apply_option & ApplyOption_FlushDataCache) != 0) {
|
if ((apply_option & ApplyOption_FlushDataCache) != 0) {
|
||||||
if (IsHeapPhysicalAddress(next_entry.phys_addr)) {
|
if (IsHeapPhysicalAddress(next_entry.phys_addr)) {
|
||||||
cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
KScopedInterruptEnable ei;
|
KScopedInterruptEnable ei;
|
||||||
|
|
||||||
const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) };
|
const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) };
|
||||||
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params));
|
static_cast<void>(KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle any pending dpc. */
|
/* Handle any pending dpc. */
|
||||||
@ -116,7 +116,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
MESOSPHERE_ASSERT(k_sp != Null<KVirtualAddress>);
|
MESOSPHERE_ASSERT(k_sp != Null<KVirtualAddress>);
|
||||||
|
|
||||||
/* Ensure that the stack pointers are aligned. */
|
/* Ensure that the stack pointers are aligned. */
|
||||||
@ -157,8 +157,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
/* Lock the context, if we're a main thread. */
|
/* Lock the context, if we're a main thread. */
|
||||||
m_locked = is_main;
|
m_locked = is_main;
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) {
|
void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) {
|
||||||
|
|||||||
@ -306,15 +306,14 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK
|
|||||||
mov x0, #1
|
mov x0, #1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */
|
/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, u32 value) */
|
||||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits
|
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj, "ax", %progbits
|
||||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv
|
.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj
|
||||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function
|
.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj, %function
|
||||||
.balign 0x10
|
.balign 0x10
|
||||||
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv:
|
_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvj:
|
||||||
/* Just load and store a u32. */
|
/* Just store a u32. */
|
||||||
ldr w2, [x1]
|
sttr w1, [x0]
|
||||||
sttr w2, [x0]
|
|
||||||
|
|
||||||
/* We're done. */
|
/* We're done. */
|
||||||
mov x0, #1
|
mov x0, #1
|
||||||
|
|||||||
@ -660,8 +660,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
ptm.Open(table_virt_addr, 1);
|
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. */
|
/* Save the page. Note that it is a pre-condition that the page is cleared, when allocated from the system page table manager. */
|
||||||
/* NOTE: Nintendo does not check the result of StoreDataCache. */
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize));
|
||||||
cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize);
|
|
||||||
g_reserved_table_phys_addr = table_phys_addr;
|
g_reserved_table_phys_addr = table_phys_addr;
|
||||||
|
|
||||||
/* Reserve an asid to correspond to no device. */
|
/* Reserve an asid to correspond to no device. */
|
||||||
@ -710,7 +709,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
/* Install interrupt handler. */
|
/* Install interrupt handler. */
|
||||||
#if defined(MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT)
|
#if defined(MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT)
|
||||||
{
|
{
|
||||||
Kernel::GetInterruptManager().BindHandler(std::addressof(g_mc_interrupt_task), KInterruptName_MemoryController, GetCurrentCoreId(), KInterruptController::PriorityLevel_High, true, true);
|
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_mc_interrupt_task), KInterruptName_MemoryController, GetCurrentCoreId(), KInterruptController::PriorityLevel_High, true, true));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -806,7 +805,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
|
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
|
||||||
|
|
||||||
ptm.Open(table_vaddr, 1);
|
ptm.Open(table_vaddr, 1);
|
||||||
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize));
|
||||||
m_tables[i] = table_vaddr;
|
m_tables[i] = table_vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +1041,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
if (l2_index == 0 && util::IsAligned(GetInteger(phys_addr), DeviceLargePageSize) && remaining >= DeviceLargePageSize) {
|
if (l2_index == 0 && util::IsAligned(GetInteger(phys_addr), DeviceLargePageSize) && remaining >= DeviceLargePageSize) {
|
||||||
/* Set the large page. */
|
/* Set the large page. */
|
||||||
l1[l1_index].SetLargePage(read, write, true, phys_addr);
|
l1[l1_index].SetLargePage(read, write, true, phys_addr);
|
||||||
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
|
||||||
|
|
||||||
/* Synchronize. */
|
/* Synchronize. */
|
||||||
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
||||||
@ -1062,11 +1061,11 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
const KVirtualAddress table_vaddr = ptm.Allocate();
|
const KVirtualAddress table_vaddr = ptm.Allocate();
|
||||||
R_UNLESS(table_vaddr != Null<KVirtualAddress>, svc::ResultOutOfMemory());
|
R_UNLESS(table_vaddr != Null<KVirtualAddress>, svc::ResultOutOfMemory());
|
||||||
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
|
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
|
||||||
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize));
|
||||||
|
|
||||||
/* Set the l1 table. */
|
/* Set the l1 table. */
|
||||||
l1[l1_index].SetTable(true, true, true, GetPageTablePhysicalAddress(table_vaddr));
|
l1[l1_index].SetTable(true, true, true, GetPageTablePhysicalAddress(table_vaddr));
|
||||||
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
|
||||||
|
|
||||||
/* Synchronize. */
|
/* Synchronize. */
|
||||||
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
||||||
@ -1093,7 +1092,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
/* Add a reference to the l2 page (from the l2 entry page). */
|
/* Add a reference to the l2 page (from the l2 entry page). */
|
||||||
ptm.Open(KVirtualAddress(l2), 1);
|
ptm.Open(KVirtualAddress(l2), 1);
|
||||||
}
|
}
|
||||||
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
|
||||||
|
|
||||||
/* Invalidate the page table cache. */
|
/* 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) {
|
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
|
||||||
@ -1199,7 +1198,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
++num_closed;
|
++num_closed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
|
||||||
|
|
||||||
/* Invalidate the page table cache. */
|
/* 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) {
|
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
|
||||||
@ -1243,7 +1242,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
if (ptm.Close(KVirtualAddress(l2), num_closed)) {
|
if (ptm.Close(KVirtualAddress(l2), num_closed)) {
|
||||||
/* Invalidate the l1 entry. */
|
/* Invalidate the l1 entry. */
|
||||||
l1[l1_index].Invalidate();
|
l1[l1_index].Invalidate();
|
||||||
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
|
||||||
|
|
||||||
/* Synchronize. */
|
/* Synchronize. */
|
||||||
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
||||||
@ -1266,7 +1265,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
|
|
||||||
/* Invalidate the entry. */
|
/* Invalidate the entry. */
|
||||||
l1[l1_index].Invalidate();
|
l1[l1_index].Invalidate();
|
||||||
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry));
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
|
||||||
|
|
||||||
/* Synchronize. */
|
/* Synchronize. */
|
||||||
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
|
||||||
|
|||||||
@ -441,7 +441,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
KThread::Register(new_thread);
|
KThread::Register(new_thread);
|
||||||
|
|
||||||
/* Run the thread. */
|
/* Run the thread. */
|
||||||
new_thread->Run();
|
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,6 +524,14 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
/* Ensure that all cores get to this point before continuing. */
|
/* Ensure that all cores get to this point before continuing. */
|
||||||
cpu::SynchronizeAllCores();
|
cpu::SynchronizeAllCores();
|
||||||
|
|
||||||
|
/* Wait 100us before continuing. */
|
||||||
|
{
|
||||||
|
const s64 timeout = KHardwareTimer::GetTick() + ams::svc::Tick(TimeSpan::FromMicroSeconds(100));
|
||||||
|
while (KHardwareTimer::GetTick() < timeout) {
|
||||||
|
__asm__ __volatile__("" ::: "memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Save the interrupt manager's state. */
|
/* Save the interrupt manager's state. */
|
||||||
Kernel::GetInterruptManager().Save(core_id);
|
Kernel::GetInterruptManager().Save(core_id);
|
||||||
|
|
||||||
|
|||||||
@ -361,10 +361,18 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
/* Return (possibly) adjusted size. */
|
/* Return (possibly) adjusted size. */
|
||||||
/* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */
|
/* 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. */
|
||||||
/* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */
|
/* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */
|
||||||
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;
|
if (kern::GetTargetFirmware() >= ams::TargetFirmware_21_0_0) {
|
||||||
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() {
|
size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() {
|
||||||
|
|||||||
@ -140,14 +140,12 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Add the previously reserved pages. */
|
/* Add the previously reserved pages. */
|
||||||
if (src_pool == dst_pool && binary_pages != 0) {
|
if (src_pool == dst_pool && binary_pages != 0) {
|
||||||
/* NOTE: Nintendo does not check the result of this operation. */
|
MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages));
|
||||||
pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the previously unreserved pages. */
|
/* Add the previously unreserved pages. */
|
||||||
for (const auto &block : unreserve_pg) {
|
for (const auto &block : unreserve_pg) {
|
||||||
/* NOTE: Nintendo does not check the result of this operation. */
|
MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(block.GetAddress(), block.GetNumPages()));
|
||||||
pg.AddBlock(block.GetAddress(), block.GetNumPages());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MESOSPHERE_ABORT_UNLESS(pg.GetNumPages() == static_cast<size_t>(params.code_num_pages));
|
MESOSPHERE_ABORT_UNLESS(pg.GetNumPages() == static_cast<size_t>(params.code_num_pages));
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace ams::kern {
|
|||||||
/* Clear and store cache. */
|
/* Clear and store cache. */
|
||||||
void * const block_address = GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block.GetAddress()));
|
void * const block_address = GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block.GetAddress()));
|
||||||
std::memset(block_address, 0xFF, block.GetSize());
|
std::memset(block_address, 0xFF, block.GetSize());
|
||||||
cpu::StoreDataCache(block_address, block.GetSize());
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(block_address, block.GetSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set remaining tracking members. */
|
/* Set remaining tracking members. */
|
||||||
|
|||||||
@ -23,8 +23,8 @@ namespace ams::kern {
|
|||||||
return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address));
|
return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool WriteToUser(KProcessAddress address, const u32 *p) {
|
ALWAYS_INLINE bool WriteToUser(KProcessAddress address, u32 val) {
|
||||||
return UserspaceAccess::CopyMemoryToUserSize32Bit(GetVoidPointer(address), p);
|
return UserspaceAccess::CopyMemoryToUserSize32Bit(GetVoidPointer(address), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool UpdateLockAtomic(u32 *out, KProcessAddress address, u32 if_zero, u32 new_orr_mask) {
|
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. */
|
/* Write the value to userspace. */
|
||||||
Result result;
|
Result result;
|
||||||
if (AMS_LIKELY(WriteToUser(addr, std::addressof(next_value)))) {
|
if (AMS_LIKELY(WriteToUser(addr, next_value))) {
|
||||||
result = ResultSuccess();
|
result = ResultSuccess();
|
||||||
} else {
|
} else {
|
||||||
result = svc::ResultInvalidCurrentMemory();
|
result = svc::ResultInvalidCurrentMemory();
|
||||||
@ -210,8 +210,8 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* If we have no waiters, clear the has waiter flag. */
|
/* If we have no waiters, clear the has waiter flag. */
|
||||||
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
|
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
|
||||||
const u32 has_waiter_flag = 0;
|
constexpr u32 HasNoWaiterFlag = 0;
|
||||||
WriteToUser(cv_key, std::addressof(has_waiter_flag));
|
WriteToUser(cv_key, HasNoWaiterFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,13 +252,13 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Write to the cv key. */
|
/* Write to the cv key. */
|
||||||
{
|
{
|
||||||
const u32 has_waiter_flag = 1;
|
constexpr u32 HasWaiterFlag = 1;
|
||||||
WriteToUser(key, std::addressof(has_waiter_flag));
|
WriteToUser(key, HasWaiterFlag);
|
||||||
cpu::DataMemoryBarrierInnerShareable();
|
cpu::DataMemoryBarrierInnerShareable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the value to userspace. */
|
/* Write the value to userspace. */
|
||||||
if (!WriteToUser(addr, std::addressof(next_value))) {
|
if (!WriteToUser(addr, next_value)) {
|
||||||
slp.CancelSleep();
|
slp.CancelSleep();
|
||||||
R_THROW(svc::ResultInvalidCurrentMemory());
|
R_THROW(svc::ResultInvalidCurrentMemory());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -416,7 +416,8 @@ namespace ams::kern {
|
|||||||
KProcess * const target = this->GetProcessUnsafe();
|
KProcess * const target = this->GetProcessUnsafe();
|
||||||
|
|
||||||
/* Terminate the process. */
|
/* Terminate the process. */
|
||||||
target->Terminate();
|
/* NOTE: This result is seemingly-intentionally not checked by Nintendo. */
|
||||||
|
static_cast<void>(target->Terminate());
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@ -1133,7 +1134,7 @@ namespace ams::kern {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDebugBase::OnExitProcess(KProcess *process) {
|
void KDebugBase::OnExitProcess(KProcess *process) {
|
||||||
MESOSPHERE_ASSERT(process != nullptr);
|
MESOSPHERE_ASSERT(process != nullptr);
|
||||||
|
|
||||||
/* Check if we're attached to a debugger. */
|
/* Check if we're attached to a debugger. */
|
||||||
@ -1148,11 +1149,9 @@ namespace ams::kern {
|
|||||||
debug->NotifyAvailable();
|
debug->NotifyAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDebugBase::OnTerminateProcess(KProcess *process) {
|
void KDebugBase::OnTerminateProcess(KProcess *process) {
|
||||||
MESOSPHERE_ASSERT(process != nullptr);
|
MESOSPHERE_ASSERT(process != nullptr);
|
||||||
|
|
||||||
/* Check if we're attached to a debugger. */
|
/* Check if we're attached to a debugger. */
|
||||||
@ -1167,21 +1166,17 @@ namespace ams::kern {
|
|||||||
debug->NotifyAvailable();
|
debug->NotifyAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDebugBase::OnExitThread(KThread *thread) {
|
void KDebugBase::OnExitThread(KThread *thread) {
|
||||||
MESOSPHERE_ASSERT(thread != nullptr);
|
MESOSPHERE_ASSERT(thread != nullptr);
|
||||||
|
|
||||||
/* Check if we're attached to a debugger. */
|
/* Check if we're attached to a debugger. */
|
||||||
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) {
|
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) {
|
||||||
/* If we are, submit the event. */
|
/* 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) };
|
const uintptr_t params[2] = { thread->GetId(), static_cast<uintptr_t>(thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread) };
|
||||||
R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params)));
|
static_cast<void>(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params)));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -167,7 +167,7 @@ namespace ams::kern {
|
|||||||
KThread::Register(new_thread);
|
KThread::Register(new_thread);
|
||||||
|
|
||||||
/* Run the thread. */
|
/* Run the thread. */
|
||||||
new_thread->Run();
|
MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
|
||||||
}
|
}
|
||||||
|
|
||||||
void KDpcManager::HandleDpc() {
|
void KDpcManager::HandleDpc() {
|
||||||
|
|||||||
@ -38,20 +38,20 @@ namespace ams::kern {
|
|||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KEvent::Signal() {
|
void KEvent::Signal() {
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
R_SUCCEED_IF(m_readable_event_destroyed);
|
if (!m_readable_event_destroyed) {
|
||||||
|
m_readable_event.Signal();
|
||||||
R_RETURN(m_readable_event.Signal());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KEvent::Clear() {
|
void KEvent::Clear() {
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
R_SUCCEED_IF(m_readable_event_destroyed);
|
if (!m_readable_event_destroyed) {
|
||||||
|
m_readable_event.Clear();
|
||||||
R_RETURN(m_readable_event.Clear());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KEvent::PostDestroy(uintptr_t arg) {
|
void KEvent::PostDestroy(uintptr_t arg) {
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
Result KHandleTable::Finalize() {
|
void KHandleTable::Finalize() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
/* Get the table and clear our record of it. */
|
/* Get the table and clear our record of it. */
|
||||||
@ -35,8 +35,6 @@ namespace ams::kern {
|
|||||||
obj->Close();
|
obj->Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KHandleTable::Remove(ams::svc::Handle handle) {
|
bool KHandleTable::Remove(ams::svc::Handle handle) {
|
||||||
|
|||||||
@ -88,7 +88,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
|
void KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
|
||||||
/* Initialize our members. */
|
/* Initialize our members. */
|
||||||
m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
|
m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
|
||||||
m_address_space_start = KProcessAddress(GetInteger(start));
|
m_address_space_start = KProcessAddress(GetInteger(start));
|
||||||
@ -130,7 +130,7 @@ namespace ams::kern {
|
|||||||
m_impl.InitializeForKernel(table, start, end);
|
m_impl.InitializeForKernel(table, start, end);
|
||||||
|
|
||||||
/* Initialize our memory block manager. */
|
/* Initialize our memory block manager. */
|
||||||
R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager));
|
MESOSPHERE_R_ABORT_UNLESS(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) {
|
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. */
|
/* Ensure cache coherency, if we're setting pages as executable. */
|
||||||
if (is_x) {
|
if (is_x) {
|
||||||
for (const auto &block : pg) {
|
for (const auto &block : pg) {
|
||||||
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize());
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()));
|
||||||
}
|
}
|
||||||
cpu::InvalidateEntireInstructionCache();
|
cpu::InvalidateEntireInstructionCache();
|
||||||
}
|
}
|
||||||
@ -2665,8 +2665,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Invalidate the block. */
|
/* Invalidate the block. */
|
||||||
if (cur_size > 0) {
|
if (cur_size > 0) {
|
||||||
/* NOTE: Nintendo does not check the result of invalidation. */
|
MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
|
||||||
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance. */
|
/* Advance. */
|
||||||
@ -2689,8 +2688,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Invalidate the last block. */
|
/* Invalidate the last block. */
|
||||||
if (cur_size > 0) {
|
if (cur_size > 0) {
|
||||||
/* NOTE: Nintendo does not check the result of invalidation. */
|
MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
|
||||||
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@ -2768,7 +2766,7 @@ namespace ams::kern {
|
|||||||
if (cur_size >= sizeof(u32)) {
|
if (cur_size >= sizeof(u32)) {
|
||||||
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
|
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
|
||||||
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
|
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
|
||||||
cpu::FlushDataCache(copy_src, copy_size);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, copy_size));
|
||||||
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(buffer, copy_src, copy_size), svc::ResultInvalidPointer());
|
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(buffer, copy_src, copy_size), svc::ResultInvalidPointer());
|
||||||
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
|
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
|
||||||
cur_addr += copy_size;
|
cur_addr += copy_size;
|
||||||
@ -2778,7 +2776,7 @@ namespace ams::kern {
|
|||||||
/* Copy remaining data. */
|
/* Copy remaining data. */
|
||||||
if (cur_size > 0) {
|
if (cur_size > 0) {
|
||||||
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
|
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
|
||||||
cpu::FlushDataCache(copy_src, cur_size);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, cur_size));
|
||||||
R_UNLESS(UserspaceAccess::CopyMemoryToUser(buffer, copy_src, cur_size), svc::ResultInvalidPointer());
|
R_UNLESS(UserspaceAccess::CopyMemoryToUser(buffer, copy_src, cur_size), svc::ResultInvalidPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2853,7 +2851,7 @@ namespace ams::kern {
|
|||||||
if (cur_size >= sizeof(u32)) {
|
if (cur_size >= sizeof(u32)) {
|
||||||
const size_t copy_size = util::AlignDown(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());
|
R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned32Bit(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, copy_size), svc::ResultInvalidCurrentMemory());
|
||||||
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size));
|
||||||
|
|
||||||
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
|
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
|
||||||
cur_addr += copy_size;
|
cur_addr += copy_size;
|
||||||
@ -2863,7 +2861,7 @@ namespace ams::kern {
|
|||||||
/* Copy remaining data. */
|
/* Copy remaining data. */
|
||||||
if (cur_size > 0) {
|
if (cur_size > 0) {
|
||||||
R_UNLESS(UserspaceAccess::CopyMemoryFromUser(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, cur_size), svc::ResultInvalidCurrentMemory());
|
R_UNLESS(UserspaceAccess::CopyMemoryFromUser(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, cur_size), svc::ResultInvalidCurrentMemory());
|
||||||
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
|
MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@ -404,7 +404,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
void KProcess::DoWorkerTaskImpl() {
|
void KProcess::DoWorkerTaskImpl() {
|
||||||
/* Terminate child threads. */
|
/* Terminate child threads. */
|
||||||
TerminateChildren(this, nullptr);
|
MESOSPHERE_R_ABORT_UNLESS(TerminateChildren(this, nullptr));
|
||||||
|
|
||||||
/* Finalize the handle table, if we're not immortal. */
|
/* Finalize the handle table, if we're not immortal. */
|
||||||
if (!m_is_immortal && m_is_handle_table_initialized) {
|
if (!m_is_immortal && m_is_handle_table_initialized) {
|
||||||
@ -420,7 +420,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
Result KProcess::StartTermination() {
|
Result KProcess::StartTermination() {
|
||||||
/* Finalize the handle table when we're done, if the process isn't immortal. */
|
/* Finalize the handle table when we're done, if the process isn't immortal. */
|
||||||
ON_SCOPE_EXIT {
|
ON_RESULT_SUCCESS {
|
||||||
if (!m_is_immortal) {
|
if (!m_is_immortal) {
|
||||||
this->FinalizeHandleTable();
|
this->FinalizeHandleTable();
|
||||||
}
|
}
|
||||||
@ -471,7 +471,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* If we need to start termination, do so. */
|
/* If we need to start termination, do so. */
|
||||||
if (needs_terminate) {
|
if (needs_terminate) {
|
||||||
this->StartTermination();
|
static_cast<void>(this->StartTermination());
|
||||||
|
|
||||||
/* Note for debug that we're exiting the process. */
|
/* Note for debug that we're exiting the process. */
|
||||||
MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name);
|
MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name);
|
||||||
@ -507,23 +507,26 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* If we need to terminate, do so. */
|
/* If we need to terminate, do so. */
|
||||||
if (needs_terminate) {
|
if (needs_terminate) {
|
||||||
/* Start termination. */
|
/* If we fail to terminate, register as a worker task. */
|
||||||
if (R_SUCCEEDED(this->StartTermination())) {
|
ON_RESULT_FAILURE {
|
||||||
/* 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. */
|
/* Note for debug that we're terminating the process. */
|
||||||
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
|
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
|
||||||
|
|
||||||
/* Register the process as a work task. */
|
/* Register the process as a work task. */
|
||||||
KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this);
|
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();
|
R_SUCCEED();
|
||||||
@ -666,7 +669,7 @@ namespace ams::kern {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
|
void KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
|
||||||
KThreadLocalPage *page_to_free = nullptr;
|
KThreadLocalPage *page_to_free = nullptr;
|
||||||
|
|
||||||
/* Release the region. */
|
/* Release the region. */
|
||||||
@ -678,7 +681,7 @@ namespace ams::kern {
|
|||||||
if (it == m_partially_used_tlp_tree.end()) {
|
if (it == m_partially_used_tlp_tree.end()) {
|
||||||
/* If we don't find it, it has to be in the fully used list. */
|
/* 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));
|
it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize));
|
||||||
R_UNLESS(it != m_fully_used_tlp_tree.end(), svc::ResultInvalidAddress());
|
MESOSPHERE_ABORT_UNLESS(it != m_fully_used_tlp_tree.end());
|
||||||
|
|
||||||
/* Release the region. */
|
/* Release the region. */
|
||||||
it->Release(addr);
|
it->Release(addr);
|
||||||
@ -710,8 +713,6 @@ namespace ams::kern {
|
|||||||
|
|
||||||
KThreadLocalPage::Free(page_to_free);
|
KThreadLocalPage::Free(page_to_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *KProcess::GetThreadLocalRegionPointer(KProcessAddress addr) {
|
void *KProcess::GetThreadLocalRegionPointer(KProcessAddress addr) {
|
||||||
@ -767,7 +768,7 @@ namespace ams::kern {
|
|||||||
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
|
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
|
||||||
|
|
||||||
if (const auto prev = m_num_running_threads--; prev == 1) {
|
if (const auto prev = m_num_running_threads--; prev == 1) {
|
||||||
this->Terminate();
|
static_cast<void>(this->Terminate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KReadableEvent::Signal() {
|
void KReadableEvent::Signal() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
KScopedSchedulerLock lk;
|
KScopedSchedulerLock lk;
|
||||||
@ -55,8 +55,6 @@ namespace ams::kern {
|
|||||||
m_is_signaled = true;
|
m_is_signaled = true;
|
||||||
this->NotifyAvailable();
|
this->NotifyAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KReadableEvent::Reset() {
|
Result KReadableEvent::Reset() {
|
||||||
|
|||||||
@ -65,7 +65,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Bind interrupt handler. */
|
/* Bind interrupt handler. */
|
||||||
Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false);
|
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
|
||||||
|
|
||||||
/* Set the current thread. */
|
/* Set the current thread. */
|
||||||
m_current_thread = GetCurrentThreadPointer();
|
m_current_thread = GetCurrentThreadPointer();
|
||||||
@ -270,7 +270,13 @@ namespace ams::kern {
|
|||||||
m_current_thread = next_thread;
|
m_current_thread = next_thread;
|
||||||
|
|
||||||
/* Set the new Thread Local region. */
|
/* Set the new Thread Local region. */
|
||||||
cpu::SwitchThreadLocalRegion(GetInteger(next_thread->GetThreadLocalRegionAddress()));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KScheduler::ClearPreviousThread(KThread *thread) {
|
void KScheduler::ClearPreviousThread(KThread *thread) {
|
||||||
|
|||||||
@ -476,8 +476,8 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Ensure that we clean up on failure. */
|
/* Ensure that we clean up on failure. */
|
||||||
ON_RESULT_FAILURE {
|
ON_RESULT_FAILURE {
|
||||||
dst_page_table.CleanupForIpcServer(dst_address, size, dst_state);
|
static_cast<void>(dst_page_table.CleanupForIpcServer(dst_address, size, dst_state));
|
||||||
src_page_table.CleanupForIpcClient(src_address, size, dst_state);
|
static_cast<void>(src_page_table.CleanupForIpcClient(src_address, size, dst_state));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Push the appropriate mapping. */
|
/* 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. */
|
/* Set up a guard to make sure that we end up in a clean state on error. */
|
||||||
ON_RESULT_FAILURE {
|
ON_RESULT_FAILURE {
|
||||||
/* Cleanup mappings. */
|
/* Cleanup mappings. */
|
||||||
CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table));
|
static_cast<void>(CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table)));
|
||||||
|
|
||||||
/* Cleanup special data. */
|
/* Cleanup special data. */
|
||||||
if (src_header.GetHasSpecialHeader()) {
|
if (src_header.GetHasSpecialHeader()) {
|
||||||
@ -835,11 +835,11 @@ namespace ams::kern {
|
|||||||
CleanupSpecialData(dst_process, dst_msg_ptr, dst_buffer_size);
|
CleanupSpecialData(dst_process, dst_msg_ptr, dst_buffer_size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr);
|
static_cast<void>(CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup mappings. */
|
/* Cleanup mappings. */
|
||||||
CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table));
|
static_cast<void>(CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table)));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ensure that the headers fit. */
|
/* Ensure that the headers fit. */
|
||||||
@ -1052,7 +1052,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Unlock the client buffer. */
|
/* Unlock the client buffer. */
|
||||||
/* NOTE: Nintendo does not check the result of this. */
|
/* NOTE: Nintendo does not check the result of this. */
|
||||||
client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size);
|
static_cast<void>(client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size));
|
||||||
|
|
||||||
/* Signal the event. */
|
/* Signal the event. */
|
||||||
event->Signal();
|
event->Signal();
|
||||||
@ -1156,7 +1156,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Unlock the client buffer. */
|
/* Unlock the client buffer. */
|
||||||
/* NOTE: Nintendo does not check the result of this. */
|
/* NOTE: Nintendo does not check the result of this. */
|
||||||
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
|
static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
|
||||||
|
|
||||||
/* Signal the event. */
|
/* Signal the event. */
|
||||||
event->Signal();
|
event->Signal();
|
||||||
@ -1284,7 +1284,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Unlock the client buffer. */
|
/* Unlock the client buffer. */
|
||||||
/* NOTE: Nintendo does not check the result of this. */
|
/* NOTE: Nintendo does not check the result of this. */
|
||||||
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
|
static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
|
||||||
|
|
||||||
/* Signal the event. */
|
/* Signal the event. */
|
||||||
event->Signal();
|
event->Signal();
|
||||||
@ -1383,7 +1383,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Unlock the buffer. */
|
/* Unlock the buffer. */
|
||||||
/* NOTE: Nintendo does not check the result of this. */
|
/* NOTE: Nintendo does not check the result of this. */
|
||||||
client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize());
|
static_cast<void>(client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize()));
|
||||||
|
|
||||||
/* Signal the event. */
|
/* Signal the event. */
|
||||||
event->Signal();
|
event->Signal();
|
||||||
|
|||||||
@ -42,7 +42,7 @@ namespace ams::kern {
|
|||||||
R_UNLESS(m_resource_size > rc_size, svc::ResultOutOfMemory());
|
R_UNLESS(m_resource_size > rc_size, svc::ResultOutOfMemory());
|
||||||
|
|
||||||
/* Initialize slab heaps. */
|
/* Initialize slab heaps. */
|
||||||
m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, PageSize);
|
R_TRY(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_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_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
|
||||||
m_block_info_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 the thread has a local region, delete it. */
|
||||||
if (m_tls_address != Null<KProcessAddress>) {
|
if (m_tls_address != Null<KProcessAddress>) {
|
||||||
MESOSPHERE_R_ABORT_UNLESS(m_parent->DeleteThreadLocalRegion(m_tls_address));
|
m_parent->DeleteThreadLocalRegion(m_tls_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release any waiters. */
|
/* Release any waiters. */
|
||||||
@ -697,7 +697,7 @@ namespace ams::kern {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) {
|
void KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
@ -712,8 +712,6 @@ namespace ams::kern {
|
|||||||
*out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask();
|
*out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KThread::SetCoreMask(int32_t core_id, u64 v_affinity_mask) {
|
Result KThread::SetCoreMask(int32_t core_id, u64 v_affinity_mask) {
|
||||||
@ -852,7 +850,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KThread::SetPriorityToIdle() {
|
void KThread::SetPriorityToIdle() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
@ -862,8 +860,6 @@ namespace ams::kern {
|
|||||||
m_priority = IdleThreadPriority;
|
m_priority = IdleThreadPriority;
|
||||||
m_base_priority = IdleThreadPriority;
|
m_base_priority = IdleThreadPriority;
|
||||||
KScheduler::OnThreadPriorityChanged(this, old_priority);
|
KScheduler::OnThreadPriorityChanged(this, old_priority);
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::RequestSuspend(SuspendType type) {
|
void KThread::RequestSuspend(SuspendType type) {
|
||||||
@ -1407,7 +1403,7 @@ namespace ams::kern {
|
|||||||
return this->GetState();
|
return this->GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KThread::Sleep(s64 timeout) {
|
void KThread::Sleep(s64 timeout) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread());
|
MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
MESOSPHERE_ASSERT(this == GetCurrentThreadPointer());
|
MESOSPHERE_ASSERT(this == GetCurrentThreadPointer());
|
||||||
@ -1422,15 +1418,13 @@ namespace ams::kern {
|
|||||||
/* Check if the thread should terminate. */
|
/* Check if the thread should terminate. */
|
||||||
if (this->IsTerminationRequested()) {
|
if (this->IsTerminationRequested()) {
|
||||||
slp.CancelSleep();
|
slp.CancelSleep();
|
||||||
R_THROW(svc::ResultTerminationRequested());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the sleep to end. */
|
/* Wait for the sleep to end. */
|
||||||
wait_queue.SetHardwareTimer(timer);
|
wait_queue.SetHardwareTimer(timer);
|
||||||
this->BeginWait(std::addressof(wait_queue));
|
this->BeginWait(std::addressof(wait_queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::BeginWait(KThreadQueue *queue) {
|
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));
|
R_RETURN(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, page_buf->GetPhysicalAddress(), KMemoryState_ThreadLocal, KMemoryPermission_UserReadWrite));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KThreadLocalPage::Finalize() {
|
void KThreadLocalPage::Finalize() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
/* Get the physical address of the page. */
|
/* Get the physical address of the page. */
|
||||||
@ -40,11 +40,10 @@ namespace ams::kern {
|
|||||||
MESOSPHERE_ABORT_UNLESS(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), this->GetAddress()));
|
MESOSPHERE_ABORT_UNLESS(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), this->GetAddress()));
|
||||||
|
|
||||||
/* Unmap the page. */
|
/* Unmap the page. */
|
||||||
R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal));
|
MESOSPHERE_R_ABORT_UNLESS(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal));
|
||||||
|
|
||||||
/* Free the page. */
|
/* Free the page. */
|
||||||
KPageBuffer::FreeChecked<PageSize>(KPageBuffer::FromPhysicalAddress(phys_addr));
|
KPageBuffer::FreeChecked<PageSize>(KPageBuffer::FromPhysicalAddress(phys_addr));
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KProcessAddress KThreadLocalPage::Reserve() {
|
KProcessAddress KThreadLocalPage::Reserve() {
|
||||||
|
|||||||
@ -67,7 +67,7 @@ namespace ams::kern {
|
|||||||
KThread::Register(thread);
|
KThread::Register(thread);
|
||||||
|
|
||||||
/* Run the thread. */
|
/* Run the thread. */
|
||||||
thread->Run();
|
MESOSPHERE_R_ABORT_UNLESS(thread->Run());
|
||||||
}
|
}
|
||||||
|
|
||||||
void KWorkerTaskManager::AddTask(WorkerType type, KWorkerTask *task) {
|
void KWorkerTaskManager::AddTask(WorkerType type, KWorkerTask *task) {
|
||||||
|
|||||||
@ -52,8 +52,8 @@ namespace ams::kern {
|
|||||||
void *idle_thread_stack = GetVoidPointer(KMemoryLayout::GetIdleStackTopAddress(core_id));
|
void *idle_thread_stack = GetVoidPointer(KMemoryLayout::GetIdleStackTopAddress(core_id));
|
||||||
KAutoObject::Create<KThread>(main_thread);
|
KAutoObject::Create<KThread>(main_thread);
|
||||||
KAutoObject::Create<KThread>(idle_thread);
|
KAutoObject::Create<KThread>(idle_thread);
|
||||||
main_thread->Initialize(nullptr, 0, main_thread_stack, 0, KThread::MainThreadPriority, core_id, nullptr, KThread::ThreadType_Main);
|
MESOSPHERE_R_ABORT_UNLESS(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);
|
MESOSPHERE_R_ABORT_UNLESS(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. */
|
/* Set the current thread to be the main thread, and we have no processes running yet. */
|
||||||
SetCurrentThread(main_thread);
|
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;
|
KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
|
||||||
|
|
||||||
/* Initialize the resource managers' shared page manager. */
|
/* Initialize the resource managers' shared page manager. */
|
||||||
g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
|
MESOSPHERE_R_ABORT_UNLESS(g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize)));
|
||||||
|
|
||||||
/* Initialize the KPageBuffer slab heap. */
|
/* Initialize the KPageBuffer slab heap. */
|
||||||
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);
|
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);
|
||||||
|
|||||||
@ -131,7 +131,7 @@ namespace ams::kern::svc {
|
|||||||
} else {
|
} else {
|
||||||
class StoreCacheOperation : public CacheOperation {
|
class StoreCacheOperation : public CacheOperation {
|
||||||
public:
|
public:
|
||||||
virtual void Operate(void *address, size_t size) const override { cpu::StoreDataCache(address, size); }
|
virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(address, size)); }
|
||||||
} operation;
|
} operation;
|
||||||
|
|
||||||
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
|
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
|
||||||
@ -158,7 +158,7 @@ namespace ams::kern::svc {
|
|||||||
} else {
|
} else {
|
||||||
class FlushCacheOperation : public CacheOperation {
|
class FlushCacheOperation : public CacheOperation {
|
||||||
public:
|
public:
|
||||||
virtual void Operate(void *address, size_t size) const override { cpu::FlushDataCache(address, size); }
|
virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(address, size)); }
|
||||||
} operation;
|
} operation;
|
||||||
|
|
||||||
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
|
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
|
||||||
|
|||||||
@ -29,7 +29,8 @@ namespace ams::kern::svc {
|
|||||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||||
R_UNLESS(event.IsNotNull(), svc::ResultInvalidHandle());
|
R_UNLESS(event.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
R_RETURN(event->Signal());
|
event->Signal();
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ClearEvent(ams::svc::Handle event_handle) {
|
Result ClearEvent(ams::svc::Handle event_handle) {
|
||||||
@ -40,7 +41,8 @@ namespace ams::kern::svc {
|
|||||||
{
|
{
|
||||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||||
if (event.IsNotNull()) {
|
if (event.IsNotNull()) {
|
||||||
R_RETURN(event->Clear());
|
event->Clear();
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +51,11 @@ namespace ams::kern::svc {
|
|||||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
||||||
if (readable_event.IsNotNull()) {
|
if (readable_event.IsNotNull()) {
|
||||||
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
|
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
|
||||||
R_RETURN(interrupt_event->Clear());
|
interrupt_event->Clear();
|
||||||
} else {
|
} else {
|
||||||
R_RETURN(readable_event->Clear());
|
readable_event->Clear();
|
||||||
}
|
}
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,7 +148,7 @@ namespace ams::kern::svc {
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* If we fail to send the message, unlock the message buffer. */
|
/* If we fail to send the message, unlock the message buffer. */
|
||||||
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); };
|
ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
|
||||||
|
|
||||||
/* Send the request. */
|
/* Send the request. */
|
||||||
MESOSPHERE_ASSERT(message != 0);
|
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. */
|
/* Ensure that if we fail and aren't terminating that we unlock the user buffer. */
|
||||||
ON_RESULT_FAILURE_BESIDES(svc::ResultTerminationRequested) {
|
ON_RESULT_FAILURE_BESIDES(svc::ResultTerminationRequested) {
|
||||||
page_table.UnlockForIpcUserBuffer(message, buffer_size);
|
static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Send the request. */
|
/* Send the request. */
|
||||||
@ -248,7 +248,7 @@ namespace ams::kern::svc {
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* If we fail to send the message, unlock the message buffer. */
|
/* If we fail to send the message, unlock the message buffer. */
|
||||||
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); };
|
ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
|
||||||
|
|
||||||
/* Reply/Receive the request. */
|
/* Reply/Receive the request. */
|
||||||
MESOSPHERE_ASSERT(message != 0);
|
MESOSPHERE_ASSERT(message != 0);
|
||||||
|
|||||||
@ -165,14 +165,14 @@
|
|||||||
HANDLER(NvHostErrInfo, 124 ) \
|
HANDLER(NvHostErrInfo, 124 ) \
|
||||||
HANDLER(RunningUlaInfo, 125 ) \
|
HANDLER(RunningUlaInfo, 125 ) \
|
||||||
HANDLER(InternalPanelInfo, 126 ) \
|
HANDLER(InternalPanelInfo, 126 ) \
|
||||||
HANDLER(ResourceLimitLimitInfo, 127 ) \
|
HANDLER(ResourceLimitInfo, 127 ) \
|
||||||
HANDLER(ResourceLimitPeakInfo, 128 ) \
|
HANDLER(ResourceLimitPeakInfoDeprecated, 128 ) \
|
||||||
HANDLER(TouchScreenInfo, 129 ) \
|
HANDLER(TouchScreenInfo, 129 ) \
|
||||||
HANDLER(AcpUserAccountSettingsInfo, 130 ) \
|
HANDLER(AcpUserAccountSettingsInfo, 130 ) \
|
||||||
HANDLER(AudioDeviceInfo, 131 ) \
|
HANDLER(AudioDeviceInfo, 131 ) \
|
||||||
HANDLER(AbnormalWakeInfo, 132 ) \
|
HANDLER(AbnormalWakeInfo, 132 ) \
|
||||||
HANDLER(ServiceProfileInfo, 133 ) \
|
HANDLER(ServiceProfileInfo, 133 ) \
|
||||||
HANDLER(BluetoothAudioInfo, 134 ) \
|
HANDLER(BluetoothAudioInfoDeprecated, 134 ) \
|
||||||
HANDLER(BluetoothPairingCountInfo, 135 ) \
|
HANDLER(BluetoothPairingCountInfo, 135 ) \
|
||||||
HANDLER(FsProxyErrorInfo2, 136 ) \
|
HANDLER(FsProxyErrorInfo2, 136 ) \
|
||||||
HANDLER(BuiltInWirelessOUIInfo, 137 ) \
|
HANDLER(BuiltInWirelessOUIInfo, 137 ) \
|
||||||
@ -188,9 +188,17 @@
|
|||||||
HANDLER(WlanIoctlErrorInfo, 147 ) \
|
HANDLER(WlanIoctlErrorInfo, 147 ) \
|
||||||
HANDLER(SdCardActivationInfo, 148 ) \
|
HANDLER(SdCardActivationInfo, 148 ) \
|
||||||
HANDLER(GameCardDetailedErrorInfo, 149 ) \
|
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(TestNx, 1000) \
|
||||||
HANDLER(NANDTypeInfo, 1001) \
|
HANDLER(NANDTypeInfo, 1001) \
|
||||||
HANDLER(NANDExtendedCsd, 1002) \
|
HANDLER(NANDExtendedCsd, 1002) \
|
||||||
|
HANDLER(BluetoothAudioInfo, 1003)
|
||||||
|
|
||||||
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
|
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
|
||||||
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
|
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
|
||||||
@ -811,16 +819,16 @@
|
|||||||
HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
|
HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
|
||||||
HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
|
HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
|
||||||
HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
|
HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
|
||||||
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemThreadCountLimit, 619, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemEventCountLimit, 620, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemSessionCountLimit, 622, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemThreadCountPeak, 624, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemEventCountPeak, 625, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(SystemSessionCountPeak, 627, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
|
HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||||
HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||||
@ -839,7 +847,7 @@
|
|||||||
HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \
|
HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||||
HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \
|
HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||||
HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(BluetoothAudioConnectionCountDeprecated, 646, BluetoothAudioInfoDeprecated, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
HANDLER(BluetoothHidPairingInfoCountDeprecated, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(BluetoothHidPairingInfoCountDeprecated, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
HANDLER(BluetoothAudioPairingInfoCountDeprecated, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(BluetoothAudioPairingInfoCountDeprecated, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
HANDLER(BluetoothLePairingInfoCountDeprecated, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
HANDLER(BluetoothLePairingInfoCountDeprecated, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||||
@ -926,6 +934,46 @@
|
|||||||
HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||||
HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
|
HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||||
HANDLER(GameCardPreviousInsertedTimestamp, 734, 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(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \
|
||||||
HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||||
HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||||
@ -960,4 +1008,5 @@
|
|||||||
HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||||
HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||||
HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||||
|
HANDLER(BluetoothAudioConnectionCount, 1034, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None )
|
||||||
|
|
||||||
|
|||||||
@ -194,6 +194,12 @@ namespace ams::erpt {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CategoryEntry {
|
||||||
|
CategoryId category;
|
||||||
|
u32 field_count;
|
||||||
|
u32 array_buffer_count;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr inline u32 FieldsPerContext = 20;
|
constexpr inline u32 FieldsPerContext = 20;
|
||||||
struct ContextEntry {
|
struct ContextEntry {
|
||||||
u32 version;
|
u32 version;
|
||||||
|
|||||||
@ -20,28 +20,33 @@
|
|||||||
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
||||||
#include <stratosphere/time/time_steady_clock_time_point.hpp>
|
#include <stratosphere/time/time_steady_clock_time_point.hpp>
|
||||||
|
|
||||||
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
|
AMS_SF_METHOD_INFO(C, H, 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, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_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, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_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, 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, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0, hos::Version_20_5_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, 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, 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, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0, hos::Version_20_5_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, 8, Result, UnregisterRunningApplicationInfo, (), (), hos::Version_21_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, 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, 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, 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, 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, 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, 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, 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, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_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, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_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, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_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, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0)
|
AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 40, Result, WaitForReportCreation, (), (), hos::Version_21_0_0)
|
||||||
|
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)
|
AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03)
|
||||||
|
|||||||
@ -124,6 +124,10 @@ namespace ams::erpt::srv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr inline bool IsValidCategory(CategoryId id) {
|
||||||
|
return FindCategoryIndex(id).has_value();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr inline CategoryId ConvertFieldToCategory(FieldId id) {
|
constexpr inline CategoryId ConvertFieldToCategory(FieldId id) {
|
||||||
const auto index = FindFieldIndex(id);
|
const auto index = FindFieldIndex(id);
|
||||||
AMS_ASSERT(index.has_value());
|
AMS_ASSERT(index.has_value());
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace ams::fatal {
|
|||||||
enum FatalPolicy : u32 {
|
enum FatalPolicy : u32 {
|
||||||
FatalPolicy_ErrorReportAndErrorScreen = 0,
|
FatalPolicy_ErrorReportAndErrorScreen = 0,
|
||||||
FatalPolicy_ErrorReport = 1,
|
FatalPolicy_ErrorReport = 1,
|
||||||
FatalPolicy_ErrorScreen = 2
|
FatalPolicy_ErrorScreen = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(ATMOSPHERE_ARCH_ARM64)
|
#if defined(ATMOSPHERE_ARCH_ARM64)
|
||||||
@ -470,6 +470,14 @@ namespace ams::fatal {
|
|||||||
#endif
|
#endif
|
||||||
static_assert(util::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
|
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 {
|
namespace srv {
|
||||||
|
|
||||||
struct ThrowContext {
|
struct ThrowContext {
|
||||||
@ -480,6 +488,7 @@ namespace ams::fatal {
|
|||||||
char proc_name[0xD];
|
char proc_name[0xD];
|
||||||
bool is_creport;
|
bool is_creport;
|
||||||
CpuContext cpu_ctx;
|
CpuContext cpu_ctx;
|
||||||
|
HashedTraceContext hashed_trace_ctx;
|
||||||
bool generate_error_report;
|
bool generate_error_report;
|
||||||
os::Event *erpt_event;
|
os::Event *erpt_event;
|
||||||
os::Event *battery_event;
|
os::Event *battery_event;
|
||||||
@ -490,7 +499,7 @@ namespace ams::fatal {
|
|||||||
u8 tls_dump[0x100];
|
u8 tls_dump[0x100];
|
||||||
|
|
||||||
ThrowContext(os::Event *erpt, os::Event *bat)
|
ThrowContext(os::Event *erpt, os::Event *bat)
|
||||||
: result(ResultSuccess()), policy(), program_id(), throw_program_id(), proc_name(), is_creport(), cpu_ctx(), generate_error_report(),
|
: result(ResultSuccess()), policy(), program_id(), throw_program_id(), proc_name(), is_creport(), cpu_ctx(), hashed_trace_ctx(), generate_error_report(),
|
||||||
erpt_event(erpt), battery_event(bat),
|
erpt_event(erpt), battery_event(bat),
|
||||||
stack_dump_size(), stack_dump_base(), stack_dump(), tls_address(), tls_dump()
|
stack_dump_size(), stack_dump_base(), stack_dump(), tls_address(), tls_dump()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -19,9 +19,10 @@
|
|||||||
#include <stratosphere/fatal/fatal_types.hpp>
|
#include <stratosphere/fatal/fatal_types.hpp>
|
||||||
#include <stratosphere/sf.hpp>
|
#include <stratosphere/sf.hpp>
|
||||||
|
|
||||||
#define AMS_FATAL_I_SERVICE_INTERFACE_INFO(C, H) \
|
#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, 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, 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, 2, Result, ThrowFatalWithCpuContext, (Result error, const sf::ClientProcessId &client_pid, fatal::FatalPolicy policy, const fatal::CpuContext &cpu_ctx), (error, client_pid, policy, cpu_ctx)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, ThrowFatalWithHashedTraceContext, (Result error, const sf::ClientProcessId &client_pid, ncm::ProgramId program_id, const fatal::HashedTraceContext &htc), (error, client_pid, program_id, htc))
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::fatal::impl, IService, AMS_FATAL_I_SERVICE_INTERFACE_INFO, 0x91328766)
|
AMS_SF_DEFINE_INTERFACE(ams::fatal::impl, IService, AMS_FATAL_I_SERVICE_INTERFACE_INFO, 0x91328766)
|
||||||
|
|||||||
@ -89,6 +89,16 @@ namespace ams::hos {
|
|||||||
Version_19_0_1 = ::ams::TargetFirmware_19_0_1,
|
Version_19_0_1 = ::ams::TargetFirmware_19_0_1,
|
||||||
Version_20_0_0 = ::ams::TargetFirmware_20_0_0,
|
Version_20_0_0 = ::ams::TargetFirmware_20_0_0,
|
||||||
Version_20_0_1 = ::ams::TargetFirmware_20_0_1,
|
Version_20_0_1 = ::ams::TargetFirmware_20_0_1,
|
||||||
|
Version_20_1_0 = ::ams::TargetFirmware_20_1_0,
|
||||||
|
Version_20_1_1 = ::ams::TargetFirmware_20_1_1,
|
||||||
|
Version_20_1_5 = ::ams::TargetFirmware_20_1_5,
|
||||||
|
Version_20_2_0 = ::ams::TargetFirmware_20_2_0,
|
||||||
|
Version_20_3_0 = ::ams::TargetFirmware_20_3_0,
|
||||||
|
Version_20_4_0 = ::ams::TargetFirmware_20_4_0,
|
||||||
|
Version_20_5_0 = ::ams::TargetFirmware_20_5_0,
|
||||||
|
Version_21_0_0 = ::ams::TargetFirmware_21_0_0,
|
||||||
|
Version_21_0_1 = ::ams::TargetFirmware_21_0_1,
|
||||||
|
Version_21_1_0 = ::ams::TargetFirmware_21_1_0,
|
||||||
|
|
||||||
Version_Current = ::ams::TargetFirmware_Current,
|
Version_Current = ::ams::TargetFirmware_Current,
|
||||||
|
|
||||||
|
|||||||
@ -94,12 +94,13 @@ namespace ams::ldr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Flag : u32 {
|
enum Flag : u32 {
|
||||||
Flag_CompressedText = (1 << 0),
|
Flag_CompressedText = (1 << 0),
|
||||||
Flag_CompressedRo = (1 << 1),
|
Flag_CompressedRo = (1 << 1),
|
||||||
Flag_CompressedRw = (1 << 2),
|
Flag_CompressedRw = (1 << 2),
|
||||||
Flag_CheckHashText = (1 << 3),
|
Flag_CheckHashText = (1 << 3),
|
||||||
Flag_CheckHashRo = (1 << 4),
|
Flag_CheckHashRo = (1 << 4),
|
||||||
Flag_CheckHashRw = (1 << 5),
|
Flag_CheckHashRw = (1 << 5),
|
||||||
|
Flag_PreventCodeReads = (1 << 6),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SegmentInfo {
|
struct SegmentInfo {
|
||||||
@ -180,6 +181,8 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
AcidFlag_PoolPartitionShift = 2,
|
AcidFlag_PoolPartitionShift = 2,
|
||||||
AcidFlag_PoolPartitionMask = (0xF << AcidFlag_PoolPartitionShift),
|
AcidFlag_PoolPartitionMask = (0xF << AcidFlag_PoolPartitionShift),
|
||||||
|
|
||||||
|
AcidFlag_LoadBrowserCoreDll = (1 << 7),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PoolPartition {
|
enum PoolPartition {
|
||||||
|
|||||||
@ -422,7 +422,7 @@ namespace ams::ncm {
|
|||||||
public:
|
public:
|
||||||
void Reset() {
|
void Reset() {
|
||||||
if (m_accessor != nullptr) {
|
if (m_accessor != nullptr) {
|
||||||
m_accessor->ReleasePin(m_pin_id);
|
static_cast<void>(m_accessor->ReleasePin(m_pin_id));
|
||||||
m_accessor = nullptr;
|
m_accessor = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,7 +479,7 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
/* Mark the memory as in use. */
|
/* Mark the memory as in use. */
|
||||||
R_RETURN(m_mapper->MarkUsing(memory.id));
|
R_RETURN(m_mapper->MarkUsing(memory.id));
|
||||||
ON_SCOPE_EXIT { this->ReleasePin(memory.id); };
|
ON_SCOPE_EXIT { static_cast<void>(this->ReleasePin(memory.id)); };
|
||||||
|
|
||||||
/* Copy out the struct. */
|
/* Copy out the struct. */
|
||||||
*out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T)));
|
*out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T)));
|
||||||
|
|||||||
@ -102,6 +102,8 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
static const SystemProgramId End;
|
static const SystemProgramId End;
|
||||||
|
|
||||||
|
static const SystemProgramId BrowserCoreDll;
|
||||||
|
|
||||||
static const SystemProgramId Manu;
|
static const SystemProgramId Manu;
|
||||||
static const SystemProgramId Htc;
|
static const SystemProgramId Htc;
|
||||||
static const SystemProgramId DmntGen2;
|
static const SystemProgramId DmntGen2;
|
||||||
@ -212,10 +214,12 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul };
|
inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul };
|
||||||
|
|
||||||
inline constexpr const SystemProgramId SystemProgramId::Manu = { 0x010000000000B14Aul };
|
inline constexpr const SystemProgramId SystemProgramId::BrowserCoreDll = { 0x010000000000085Dul };
|
||||||
inline constexpr const SystemProgramId SystemProgramId::Htc = { 0x010000000000B240ul };
|
|
||||||
inline constexpr const SystemProgramId SystemProgramId::DmntGen2 = { 0x010000000000D609ul };
|
inline constexpr const SystemProgramId SystemProgramId::Manu = { 0x010000000000B14Aul };
|
||||||
inline constexpr const SystemProgramId SystemProgramId::DevServer = { 0x010000000000D623ul };
|
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) {
|
inline constexpr bool IsSystemProgramId(const ProgramId &program_id) {
|
||||||
return (SystemProgramId::Start <= program_id && program_id <= SystemProgramId::End) || IsAtmosphereProgramId(program_id);
|
return (SystemProgramId::Start <= program_id && program_id <= SystemProgramId::End) || IsAtmosphereProgramId(program_id);
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
AMS_SF_METHOD_INFO(C, H, 8, Result, EnableApplicationCrashReport, (bool enabled), (enabled)) \
|
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, 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, 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, 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, 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)
|
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,6 +37,7 @@ namespace ams::pgl::srv {
|
|||||||
Result EnableApplicationCrashReportImpl(bool enabled);
|
Result EnableApplicationCrashReportImpl(bool enabled);
|
||||||
Result IsApplicationCrashReportEnabledImpl(bool *out);
|
Result IsApplicationCrashReportEnabledImpl(bool *out);
|
||||||
Result EnableApplicationAllThreadDumpOnCrashImpl(bool enabled);
|
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);
|
Result TriggerApplicationSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ namespace ams::pgl::srv {
|
|||||||
Result EnableApplicationCrashReport(bool enabled);
|
Result EnableApplicationCrashReport(bool enabled);
|
||||||
Result IsApplicationCrashReportEnabled(ams::sf::Out<bool> out);
|
Result IsApplicationCrashReportEnabled(ams::sf::Out<bool> out);
|
||||||
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
|
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 TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg);
|
||||||
|
|
||||||
Result GetShellEventObserver(ams::sf::Out<ams::sf::SharedPointer<pgl::sf::IEventObserver>> out);
|
Result GetShellEventObserver(ams::sf::Out<ams::sf::SharedPointer<pgl::sf::IEventObserver>> out);
|
||||||
@ -86,6 +88,7 @@ namespace ams::pgl::srv {
|
|||||||
Result EnableApplicationCrashReport(bool enabled);
|
Result EnableApplicationCrashReport(bool enabled);
|
||||||
Result IsApplicationCrashReportEnabled(ams::tipc::Out<bool> out);
|
Result IsApplicationCrashReportEnabled(ams::tipc::Out<bool> out);
|
||||||
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
|
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
|
||||||
|
Result GetProcessId(ams::tipc::Out<os::ProcessId> out, ncm::ProgramId program_id);
|
||||||
Result GetShellEventObserver(ams::tipc::OutMoveHandle out);
|
Result GetShellEventObserver(ams::tipc::OutMoveHandle out);
|
||||||
};
|
};
|
||||||
static_assert(pgl::tipc::IsIShellInterface<ShellInterfaceTipc>);
|
static_assert(pgl::tipc::IsIShellInterface<ShellInterfaceTipc>);
|
||||||
|
|||||||
@ -30,7 +30,8 @@
|
|||||||
AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \
|
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, 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, 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, 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_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ 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, 7, void, NotifyBootFinished, (), ()) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out<os::ProcessId> out), (out)) \
|
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, 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, 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_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0)
|
||||||
|
|||||||
@ -31,5 +31,6 @@ namespace ams::pm::shell {
|
|||||||
Result BoostSystemMemoryResourceLimit(u64 size);
|
Result BoostSystemMemoryResourceLimit(u64 size);
|
||||||
Result BoostApplicationThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostSystemThreadResourceLimit();
|
||||||
|
Result GetProcessId(os::ProcessId *out_process_id, const ncm::ProgramId program_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
||||||
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto
|
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto -Wno-error=unused-result
|
||||||
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
|
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
|
||||||
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
|
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
|
||||||
@ -118,7 +118,7 @@ clean:
|
|||||||
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
@echo clean $(ATMOSPHERE_BUILD_NAME) ...
|
||||||
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_OUT_DIR)
|
||||||
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
@rm -fr $(foreach hdr,$(GCH_DIRS),$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
||||||
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir $$i 2>/dev/null || true; done
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(ATMOSPHERE_BUILD_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@ -20,7 +20,7 @@ namespace ams::cs {
|
|||||||
void InitializeTargetIoServer() {
|
void InitializeTargetIoServer() {
|
||||||
/* Launch target io server. */
|
/* Launch target io server. */
|
||||||
os::ProcessId process_id;
|
os::ProcessId process_id;
|
||||||
scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0);
|
static_cast<void>(scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,9 @@ namespace ams::erpt::srv {
|
|||||||
Attachment::~Attachment() {
|
Attachment::~Attachment() {
|
||||||
this->CloseStream();
|
this->CloseStream();
|
||||||
if (m_record->RemoveReference()) {
|
if (m_record->RemoveReference()) {
|
||||||
this->DeleteStream(this->FileName().name);
|
if (R_FAILED(this->DeleteStream(this->FileName().name))) {
|
||||||
|
/* TODO: Log failure? */
|
||||||
|
}
|
||||||
delete m_record;
|
delete m_record;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,7 +81,7 @@ namespace ams::erpt::srv {
|
|||||||
oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt));
|
oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt));
|
||||||
}
|
}
|
||||||
|
|
||||||
Formatter::AddField(report, FieldId_CipherKey, cipher, sizeof(cipher));
|
R_TRY(Formatter::AddField(report, FieldId_CipherKey, cipher, s_need_to_store_cipher ? sizeof(cipher) : 1));
|
||||||
std::memset(s_key, 0, sizeof(s_key));
|
std::memset(s_key, 0, sizeof(s_key));
|
||||||
|
|
||||||
R_RETURN(Formatter::End(report));
|
R_RETURN(Formatter::End(report));
|
||||||
|
|||||||
@ -90,16 +90,15 @@ namespace ams::erpt::srv {
|
|||||||
|
|
||||||
Result Context::WriteContextsToReport(Report *report) {
|
Result Context::WriteContextsToReport(Report *report) {
|
||||||
R_TRY(report->Open(ReportOpenType_Create));
|
R_TRY(report->Open(ReportOpenType_Create));
|
||||||
|
ON_SCOPE_EXIT { report->Close(); };
|
||||||
|
|
||||||
R_TRY(Cipher::Begin(report, ContextRecord::GetRecordCount()));
|
R_TRY(Cipher::Begin(report, ContextRecord::GetRecordCount()));
|
||||||
|
|
||||||
for (auto it = g_category_list.begin(); it != g_category_list.end(); it++) {
|
for (auto it = g_category_list.begin(); it != g_category_list.end(); it++) {
|
||||||
R_TRY(it->AddCategoryToReport(report));
|
R_TRY(it->AddCategoryToReport(report));
|
||||||
}
|
}
|
||||||
|
|
||||||
Cipher::End(report);
|
R_RETURN(Cipher::End(report));
|
||||||
report->Close();
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Context::ClearContext(CategoryId cat) {
|
Result Context::ClearContext(CategoryId cat) {
|
||||||
|
|||||||
@ -23,6 +23,59 @@
|
|||||||
|
|
||||||
namespace ams::erpt::srv {
|
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) {
|
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 ContextEntry *ctx = reinterpret_cast<const ContextEntry *>( ctx_buffer.GetPointer());
|
||||||
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
|
const u8 *data = reinterpret_cast<const u8 *>(data_buffer.GetPointer());
|
||||||
@ -85,6 +138,28 @@ namespace ams::erpt::srv {
|
|||||||
R_SUCCEED();
|
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) {
|
Result ContextImpl::SubmitMultipleCategoryContext(const MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer) {
|
||||||
R_UNLESS(ctx_entry.category_count <= CategoriesPerMultipleCategoryContext, erpt::ResultInvalidArgument());
|
R_UNLESS(ctx_entry.category_count <= CategoriesPerMultipleCategoryContext, erpt::ResultInvalidArgument());
|
||||||
|
|
||||||
@ -114,6 +189,10 @@ namespace ams::erpt::srv {
|
|||||||
R_SUCCEED();
|
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() {
|
Result ContextImpl::UpdateApplicationLaunchTime() {
|
||||||
Reporter::UpdateApplicationLaunchTime();
|
Reporter::UpdateApplicationLaunchTime();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@ -124,6 +203,16 @@ namespace ams::erpt::srv {
|
|||||||
R_SUCCEED();
|
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) {
|
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 char *name = reinterpret_cast<const char *>(attachment_name.GetPointer());
|
||||||
const u8 *data = reinterpret_cast<const u8 *>(attachment_data.GetPointer());
|
const u8 *data = reinterpret_cast<const u8 *>(attachment_data.GetPointer());
|
||||||
@ -211,7 +300,12 @@ namespace ams::erpt::srv {
|
|||||||
|
|
||||||
Result ContextImpl::InvalidateForcedShutdownDetection() {
|
Result ContextImpl::InvalidateForcedShutdownDetection() {
|
||||||
/* NOTE: Nintendo does not check the result here. */
|
/* NOTE: Nintendo does not check the result here. */
|
||||||
erpt::srv::InvalidateForcedShutdownDetection();
|
static_cast<void>(erpt::srv::InvalidateForcedShutdownDetection());
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ContextImpl::WaitForReportCreation() {
|
||||||
|
/* This function currently does nothing. Maybe it only waits on Ounce? */
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,9 +26,13 @@ namespace ams::erpt::srv {
|
|||||||
Result ClearInitialLaunchSettingsCompletionTime();
|
Result ClearInitialLaunchSettingsCompletionTime();
|
||||||
Result UpdatePowerOnTime();
|
Result UpdatePowerOnTime();
|
||||||
Result UpdateAwakeTime();
|
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 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 UpdateApplicationLaunchTime();
|
||||||
|
Result RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id);
|
||||||
Result ClearApplicationLaunchTime();
|
Result ClearApplicationLaunchTime();
|
||||||
|
Result UnregisterRunningApplicationInfo();
|
||||||
Result SubmitAttachment(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data);
|
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 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);
|
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);
|
||||||
@ -41,6 +45,7 @@ namespace ams::erpt::srv {
|
|||||||
Result UnregisterRunningApplet(ncm::ProgramId program_id);
|
Result UnregisterRunningApplet(ncm::ProgramId program_id);
|
||||||
Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration);
|
Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration);
|
||||||
Result InvalidateForcedShutdownDetection();
|
Result InvalidateForcedShutdownDetection();
|
||||||
|
Result WaitForReportCreation();
|
||||||
};
|
};
|
||||||
static_assert(erpt::sf::IsIContext<ContextImpl>);
|
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. */
|
/* Check if the forced shutdown context exists; if it doesn't, we should create an empty one. */
|
||||||
if (!IsForceShutdownDetected()) {
|
if (!IsForceShutdownDetected()) {
|
||||||
/* NOTE: Nintendo does not check result here. */
|
/* NOTE: Nintendo does not check result here. */
|
||||||
CreateForcedShutdownContext();
|
static_cast<void>(CreateForcedShutdownContext());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the forced shutdown context. */
|
/* Load the forced shutdown context. */
|
||||||
/* NOTE: Nintendo does not check that this succeeds. */
|
/* NOTE: Nintendo does not check that this succeeds. */
|
||||||
LoadForcedShutdownContext();
|
static_cast<void>(LoadForcedShutdownContext());
|
||||||
|
|
||||||
/* Create report for the forced shutdown. */
|
/* Create report for the forced shutdown. */
|
||||||
/* NOTE: Nintendo does not check that this succeeds. */
|
/* NOTE: Nintendo does not check that this succeeds. */
|
||||||
CreateReportForForcedShutdown();
|
static_cast<void>(CreateReportForForcedShutdown());
|
||||||
|
|
||||||
/* Clear the forced shutdown categories. */
|
/* Clear the forced shutdown categories. */
|
||||||
/* NOTE: Nintendo does not check that this succeeds. */
|
/* NOTE: Nintendo does not check that this succeeds. */
|
||||||
Context::ClearContext(CategoryId_RunningApplicationInfo);
|
static_cast<void>(Context::ClearContext(CategoryId_RunningApplicationInfo));
|
||||||
Context::ClearContext(CategoryId_RunningAppletInfo);
|
static_cast<void>(Context::ClearContext(CategoryId_RunningAppletInfo));
|
||||||
Context::ClearContext(CategoryId_FocusedAppletHistoryInfo);
|
static_cast<void>(Context::ClearContext(CategoryId_FocusedAppletHistoryInfo));
|
||||||
|
|
||||||
/* Save the forced shutdown context. */
|
/* Save the forced shutdown context. */
|
||||||
/* NOTE: Nintendo does not check that this succeeds. */
|
/* NOTE: Nintendo does not check that this succeeds. */
|
||||||
SaveForcedShutdownContext();
|
static_cast<void>(SaveForcedShutdownContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeForcedShutdownDetection() {
|
void FinalizeForcedShutdownDetection() {
|
||||||
@ -265,7 +265,7 @@ namespace ams::erpt::srv {
|
|||||||
|
|
||||||
void SaveForcedShutdownContext() {
|
void SaveForcedShutdownContext() {
|
||||||
/* NOTE: Nintendo does not check that saving the report succeeds. */
|
/* NOTE: Nintendo does not check that saving the report succeeds. */
|
||||||
SaveForcedShutdownContextImpl();
|
static_cast<void>(SaveForcedShutdownContextImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubmitContextForForcedShutdownDetection(const ContextEntry *entry, const u8 *data, u32 data_size) {
|
void SubmitContextForForcedShutdownDetection(const ContextEntry *entry, const u8 *data, u32 data_size) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user