Compare commits

...

99 Commits

Author SHA1 Message Date
5cb085b00c daybreak: Add firmware compatibility gate and German UI
Block unsupported firmware updates via a dedicated dialog using
Exosphere's maximum supported HOS version, and translate the Daybreak
interface to German.
2026-05-17 12:59:14 +02:00
hexkyz
2c7e2bfaae Merge pull request #2800 from masagrator/patch-1
fs.mitm: Add "Until Then" as another game which needs stolen heap for layeredfs
2026-04-25 19:55:43 +01:00
MasaGratoR
e655fd4b01 fs.mitm: Add "Until Then" as another game which needs stolen heap for layeredfs 2026-04-24 22:30:25 +02:00
hexkyz
022000f668 docs: add changelog for 1.11.1
this was missing from the usual enum recognition changes
synchronization will happen at a future release instead
2026-04-07 22:53:21 +01:00
hexkyz
d04c20a049 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "82f1553c4"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "82f1553c4"
git-subrepo:
  version:  "0.4.9"
  origin:   "???"
  commit:   "???"
2026-04-07 17:24:31 +01:00
hexkyz
252f8685b4 Merge pull request #2786 from alula/alula
ams: add enum recognition for 22.1.0
2026-04-07 17:22:46 +01:00
Alula
020ed307b1 ams: add enum recognition for 22.1.0 2026-04-07 03:22:37 +02:00
hexkyz
d9e1d799ab git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "3726bfd65"
upstream:
  origin:   "https://github.com/m4xw/emummc"
  branch:   "develop"
  commit:   "3726bfd65"
git-subrepo:
  version:  "0.4.9"
  origin:   "???"
  commit:   "???"
2026-04-05 20:34:44 +01:00
ndeadly
80bd459516 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "8e9c9ab16"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "8e9c9ab16"
git-subrepo:
  version:  "0.4.9"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5e0f401"
2026-04-04 16:44:08 +02:00
hexkyz
931e3c37fd docs: add changelog for 1.11.0 2026-04-03 23:34:13 +01:00
hexkyz
4b4db91341 pgl: no need to initialize lr services when already using our own 2026-04-03 23:32:15 +01:00
hexkyz
e3fc339fe5 Merge pull request #2766 from alula/erpt-crash-fix
erpt: Fix rare aborts caused by ResultInvalidPowerState
2026-04-03 23:09:55 +01:00
Alula
a051c3c723 erpt: document unknown 0x20000 flag 2026-04-04 00:06:49 +02:00
Alula
9a1ea02c8c erpt: Add some missed 20.0.0+ FsInfo changes 2026-04-04 00:06:49 +02:00
hexkyz
bae1ad22ec Merge pull request #2768 from masagrator/patch-1
Update services in PGL to match 21.0.0
2026-04-03 22:33:28 +01:00
hexkyz
cd1503a9ca emummc: fix offsets
22.0.0 now boots under emummc
2026-04-03 22:31:19 +01:00
Alula
72e3b0dd34 erpt: Fix rare aborts caused by ResultInvalidPowerState 2026-04-03 22:55:09 +02:00
MasaGratoR
ac120cf84b Match 21.0.0 FW 2026-04-03 22:23:08 +02:00
MasaGratoR
97ffad2ab6 Update service access to match 21.0.0 2026-04-03 22:22:15 +02:00
hexkyz
c8d68a3a8a Merge pull request #2763 from masagrator/patch-1
Fix off by 1 bug + allocation error + missing initialize in PGL
2026-04-03 19:27:56 +01:00
hexkyz
8987d642d1 Merge pull request #2748 from CTCaer/auto_dram_cfg
[Feature] Auto dram cfg & Auto memory mode
2026-04-03 19:27:38 +01:00
hexkyz
7ffb1da2ac Merge pull request #2734 from ndeadly/r_discard
libvapours: add R_DISCARD macro
2026-04-03 19:27:19 +01:00
hexkyz
5c426bf90d loader: remove unused file 2026-04-03 19:09:28 +01:00
MasaGratoR
31ca20f3b7 Add missing libstratosphere lr::Initialize() 2026-04-02 21:09:15 +02:00
MasaGratoR
174da786e4 Override new and delete operators 2026-04-02 20:45:30 +02:00
hexkyz
93a82c0441 loader: patch am to recover homebrew compatibility
This patch is to be removed if/once hbmenu/libnx re-designs the exiting logic
2026-04-02 01:42:53 +01:00
hexkyz
082115187a loader/util: fully implement zstd bic variant
Implement both compression and decompression utilities and simplify loader logic
2026-04-02 01:30:45 +01:00
hexkyz
db388385b0 Merge pull request #2761 from alula/22_support
22.0.0 support part 3
2026-04-02 01:17:19 +01:00
MasaGratoR
4a8f7628c2 Update pgl_srv_shell_host_utils.cpp 2026-04-01 20:44:08 +02:00
MasaGratoR
9d16ee6a74 Update pgl_srv_shell_host_utils.cpp 2026-04-01 20:41:25 +02:00
MasaGratoR
3b9ee08c69 Update pgl_srv_shell_host_utils.cpp 2026-04-01 20:33:27 +02:00
MasaGratoR
2694f31eb3 Update pgl_srv_shell_host_utils.cpp 2026-04-01 20:31:47 +02:00
MasaGratoR
f3f1fa46ed Fix off by 1 bug 2026-04-01 20:17:52 +02:00
Alula
8a7c2872c3 erpt: use official name for erpt::IManager cmd 7 2026-04-01 05:57:28 +02:00
Alula
6acdc05c89 erpt: revert GetReportSizeMax to not potentially break old firmwares 2026-04-01 05:46:04 +02:00
hexkyz
32bb6b17ab Merge pull request #2753 from alula/22_support
Basic ("the console boots and functions as expected") 22.0.0 support - Part 2
2026-04-01 03:10:19 +01:00
Alula
27455329b3 loader: update for 22.0.0 2026-03-28 01:43:19 +01:00
Alula
7d334f09ee loader: the two unknown titles are LGE/LGP for China 2026-03-27 23:57:44 +01:00
Alula
8c0ff851f2 loader/strat: Add amalgamated zstd 1.5.7 with ZBIC patches 2026-03-27 23:51:04 +01:00
hexkyz
b108318996 Merge pull request #2744 from alula/22_support
Basic ("the console boots and functions as expected") 22.0.0 support
2026-03-20 00:22:10 +00:00
hexkyz
5dfdc6e8b0 Merge emummc changes from pull request #2743
Remaining changes are duplicated in pull request #2744
2026-03-20 00:17:19 +00:00
hexkyz
14e63cb04c loader: add USB 3.0 patches for 22.0.0
Additionally remove duplicated entry for 20.1.0, just use the 20.0.0 one.
2026-03-20 00:02:42 +00:00
CTCaer
5dd9816e3c exosphere: allow memory mode to be used on retail 2026-03-19 16:35:36 +02:00
CTCaer
5a5d9b206b exosphere: automatically adjust dram id if needed
Checks if programmed memory size matches the one from fused dram id.
If not, adjust it properly so PCV can do proper training and not crash.
2026-03-19 16:32:12 +02:00
Alula
49e2330ed8 erpt: rename old ControllerStyleList field 2026-03-18 23:40:40 +01:00
Alula
1847db06f8 erpt: Implement 22.0.0 commands and changes
Co-authored-by: nvnprogram <97150065+nvnprogram@users.noreply.github.com>
2026-03-18 23:33:55 +01:00
Alula
f028802fb8 erpt: make FieldType u8 to match Nintendo 2026-03-18 23:30:06 +01:00
Alula
b29dbeae3d kern: don't allow mapping device pages as executable on abi 26.x+ 2026-03-18 23:25:24 +01:00
Alula
4e653f67e5 kern: make KProcess layout accurate to N's code 2026-03-18 23:25:24 +01:00
Alula
a985bdb1d4 kern: N made this an u32 for some reason 2026-03-18 23:25:24 +01:00
Alula
5b0a4830d4 pinmux: add a build time option to configure JC rail uart 2026-03-18 23:25:24 +01:00
Alula
26990b3be9 fs: DisableAutoSaveDataCreation was removed in 22 2026-03-18 23:25:24 +01:00
Alula
76bceffbd5 svc: bump supported kernel version 2026-03-18 23:25:24 +01:00
Alula
0ee6277be9 kern: write thread handle to tls +0x110 on creation 2026-03-18 23:25:24 +01:00
Alula
9cc82c6f80 fusee/exo/ams: update with new keydata/version enums 2026-03-18 23:25:24 +01:00
hexkyz
6b831406d6 erpt: style fix 2026-03-18 21:35:18 +00:00
hexkyz
23ebd4d677 erpt: add new IDs for 22.0.0 2026-03-18 21:32:35 +00:00
hexkyz
00f987dd38 erpt: types are now a byte in 22.0.0 2026-03-18 21:18:05 +00:00
ndeadly
f8a5a6c015 libvapours: add R_DISCARD macro 2026-02-23 01:09:11 +01:00
hexkyz
61ac03e22d Merge pull request #2703 from HydrationMan/master
Update fusee_display.cpp - add missing newline
2026-02-05 21:47:59 +00:00
hexkyz
208b60696c Merge pull request #2726 from ndeadly/svc-shim-compat
libstrat: update GetDebugEvent svc shim for compatibility with libnx changes
2026-02-05 21:37:17 +00:00
ndeadly
dfb936ed11 libstrat: update GetDebugEvent svc shim for compatibility with libnx changes 2026-02-03 22:59:47 +01:00
Michael Scire
5056ab21af git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "9a8703e71"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "9a8703e71"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2026-01-15 15:39:39 -07:00
Michael Scire
eb34f9789c git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "8ab963b0b"
upstream:
  origin:   "https://github.com/m4xw/emummc"
  branch:   "develop"
  commit:   "8ab963b0b"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2026-01-13 23:25:52 -07:00
Michael Scire
1e88f37892 ams/emummc: update for 21.2.0 2026-01-13 23:24:53 -07:00
Kane
cd72f9f33e Update fusee_display.cpp - add missing newline
Add newline that would otherwise cause text concatenation when it comes to suggestedFix content being appended.
2026-01-01 23:16:38 +13:00
Michael Scire
21c0f75a29 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "6cc765fca"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "6cc765fca"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2025-12-08 18:41:44 -07:00
Michael Scire
3cb5d5f957 ams: add enum recognition for 21.1.0 2025-12-08 18:41:01 -07:00
Michael Scire
00d1cdb533 loader: fix valid-nso-set checks to be accurate (closes #2660) 2025-11-22 15:57:35 -07:00
Michael Scire
d9fc6e99eb kern: eshop actually requires an extra mb 2025-11-15 17:35:47 -07:00
Michael Scire
c08a13a546 loader: add USB 3.0 patches for 21.0.0 2025-11-15 17:03:49 -07:00
Michael Scire
b5b6189c85 kern: fix comparison typo 2025-11-15 16:51:15 -07:00
Michael Scire
28a378ca0d ro: fix loading of aligned-header NROs 2025-11-15 16:47:57 -07:00
Michael Scire
540d00e097 kern: 21.0.0 requires an even smaller memory pool... 2025-11-15 16:47:44 -07:00
Michael Scire
bfe98bc5b8 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "6e2c09c79"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "6e2c09c79"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2025-11-15 12:58:41 -07:00
Michael Scire
4928bcb003 git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "3c57b20ba"
upstream:
  origin:   "https://github.com/m4xw/emummc"
  branch:   "develop"
  commit:   "3c57b20ba"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2025-11-15 12:57:18 -07:00
Michael Scire
d61ee942d9 docs: add changelog for 1.10.0 2025-11-15 12:55:47 -07:00
Michael Scire
f59e6a936b emummc: update for 21.0.0 2025-11-15 12:31:07 -07:00
Michael Scire
129c61c256 loader: fix sd-cmpt 2025-11-15 12:31:07 -07:00
Michael Scire
db71eefd9f loader: update for 20.0.0/21.0.0 2025-11-15 12:31:07 -07:00
Michael Scire
4b32a2b964 pgl/pm: add GetProcessId command 2025-11-15 12:31:07 -07:00
Michael Scire
0fb9481e59 kern: fix debug build for [[nodiscard]] changes 2025-11-15 12:31:07 -07:00
Michael Scire
c05d91f44a kern: fix whoops introduced by nodiscard refactor 2025-11-15 12:31:07 -07:00
Michael Scire
e1d82a13f3 erpt: implement new 21.0.0 commands 2025-11-15 12:31:07 -07:00
Michael Scire
4f1201a022 erpt: fix ids, failed to copy the new categories 2025-11-15 12:31:07 -07:00
Michael Scire
4201bbff63 fatal: add new HashedTraceContext command 2025-11-15 12:31:07 -07:00
Michael Scire
94c36a3255 erpt: add new IDs for 21.0.0 2025-11-15 12:31:07 -07:00
Michael Scire
6b0ef21b83 kern: RESERVED_2F now set by HandleFpuException 2025-11-15 12:31:07 -07:00
Michael Scire
ac382f69e7 kern: exception flags are now atomic.
This is a really weird one, because they didn't actually update the
code which updates these flags in asm, these still use ldrb/orr/strb.
But every access to these via c++ is now an atomic ldxrb/stxrb loop.
Maybe they just forgot to update the asm?
2025-11-15 12:31:07 -07:00
Michael Scire
2a44550dbe kern: pass u32 directly to CopyMemoryToUserSize32Bit 2025-11-15 12:31:07 -07:00
Michael Scire
3bc1951820 ams: mark ams::Result [[nodiscard]] (partially complete).
NOTE: This work is not yet fully complete; kernel is done, but
it was taking an exceedingly long time to get through libstratosphere.
Thus, I've temporarily added -Wno-error=unused-result for libstratosphere/stratosphere.

All warnings should be fixed to do the same thing Nintendo does as relevant, but this
is taking a phenomenally long time and is not actually the most important work to do,
so it can be put off for some time to prioritize other tasks for 21.0.0 support.
2025-11-15 12:31:07 -07:00
Michael Scire
418fde40a8 kern: Nintendo now also devirtualizes KAutoObject::DynamicCast 2025-11-15 12:31:07 -07:00
Michael Scire
e36051359c kern: write cpu tick differential to tls +0x108 on thread switch 2025-11-15 12:31:07 -07:00
Michael Scire
18bb1fdea0 fusee/exo/ams: update with new keydata/version enums 2025-11-15 12:31:07 -07:00
Michael Scire
c8e39a54d2 fs.mitm: add another game which needs stolen heap for layeredfs 2025-10-07 23:12:07 -07:00
Michael Scire
11a46e4579 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "583ae0fbf"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "583ae0fbf"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2025-10-07 17:34:00 -07:00
Michael Scire
652519da2e fssystem: fix support for parsing newer-format BKTR NCAs
Apparently, at some point they started allowing maxlayers=3, which caused this code to not work.

Looking at latest FS, they always reference DataStorage instead of level+2 for the final level.

This fixes parsing update romfs for newer games, e.g. Super Mario Galaxy 2.
2025-10-07 17:30:12 -07:00
Michael Scire
de9b02007b git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "efd3d931a"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "efd3d931a"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2025-09-29 18:45:20 -07:00
Michael Scire
982f0e4fd4 ams: bump version, add enum support for 20.5.0 2025-09-29 18:44:40 -07:00
182 changed files with 58826 additions and 1056 deletions

View File

@@ -15,6 +15,13 @@
# Desc: Controls whether userland has access to the PMU registers. # Desc: Controls whether userland has access to the PMU registers.
# NOTE: It is unknown what effects this has on official code. # NOTE: It is unknown what effects this has on official code.
# Key: enable_mem_mode, default: 0.
# Desc: Controls whether boot config memory mode is taken into account
# for retail units. This does not affect development units.
# NOTE: On retail units max ram size is capped to 4GB.
# Enabling this will use the boot config memory mode parameter,
# which by default is auto and size gets set based on physical size.
# Key: blank_prodinfo_sysmmc, default: 0. # Key: blank_prodinfo_sysmmc, default: 0.
# Desc: Controls whether PRODINFO should be blanked in sysmmc. # Desc: Controls whether PRODINFO should be blanked in sysmmc.
# This will cause the system to see dummied out keys and # This will cause the system to see dummied out keys and
@@ -51,6 +58,7 @@ debugmode=1
debugmode_user=0 debugmode_user=0
disable_user_exception_handlers=0 disable_user_exception_handlers=0
enable_user_pmu_access=0 enable_user_pmu_access=0
enable_mem_mode=0
blank_prodinfo_sysmmc=0 blank_prodinfo_sysmmc=0
blank_prodinfo_emummc=0 blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0 allow_writing_to_cal_sysmmc=0

View File

@@ -1,5 +1,60 @@
# Changelog # Changelog
## 1.9.3 ## 1.11.1
+ Basic support was added for 22.1.0.
+ General system stability improvements to enhance the user's experience.
## 1.11.0
+ Support was added for 22.0.0.
+ Special thanks to @alula for handling a large chunk of the necessary kernel, loader and erpt changes.
+ The console should boot and atmosphère should be fully functional.
+ **Please note**: A change in how applications/applets' lifespan is managed broke the homebrew ecosystem.
+ All applications and applets are expected to perform a clean exit by calling the relevant IPC commands.
+ Homebrew compiled with libnx and hbmenu itself explicitly avoid exiting so it can keep using the same process.
+ Properly fixing this would require a re-design of how homebrew is launched and terminated.
+ As a temporary solution, patches to the `am` sysmodule are now included which allow restoring the previous behavior and regain homebrew compatibility without any further changes.
+ Nonetheless, please report any issues you may face when testing homebrew to ensure no edge cases have been missed.
+ `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.
+ `erpt` was updated to reflect the latest official behavior.
+ `pgl` was updated to fix a few issues.
+ Support was added for memory modes above 4GB (thanks @CTCaer).
+ A build time option to configure Joy-Con rails as UART for debugging was added (thanks @alula).
+ General system stability improvements to enhance the user's experience.
## 1.10.2
+ Basic support was added for 21.2.0.
+ General system stability improvements to enhance the user's experience.
## 1.10.1
+ Basic support was added for 21.1.0.
+ A bug was fixed that caused some games (e.g. Tomb Raider definitive edition) to fail to launch.
+ General system stability improvements to enhance the user's experience.
## 1.10.0
+ Basic support was added for 21.0.0.
+ The console should boot and atmosphère should be fully functional.
+ **Please note**: All homebrew software may need to be re-compiled with the latest libnx (>= 4.10.0), or else it may crash/experience memory corruption.
+ Nintendo broke the userland<->kernel TLS ABI in 21.0.0, by writing to previously reserved space.
+ Homebrew used this reserved space for its TLS slots, which means any homebrew software using TLS slots will experience memory corruption when running under Atmosphere 1.10.0.
+ This doesn't appear to impact everything, but a large portion of tested homebrew crashes (often on exit), and so will need re-compile for the new ABI.
+ For those technically inclined, while TLS slots are rarely used by developers, they're used to implement features like e.g. C++ exceptions under the hood, and so anything using those crashes, etc.
+ To help make this transition easier, hbmenu now shows a warning when selecting homebrew compiled with an older, incompatible ABI version.
+ I apologize for the hassle in general.
+ libnx has been updated so that its reserved space matches Nintendo's now -- this particular issue can never occur again, even if Nintendo touches more reserved space.
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
+ `mesosphère` was updated to reflect the latest official kernel behavior.
+ `loader` was updated to reflect the latest official behavior.
+ `pm` was updated to reflect the latest official behavior.
+ `erpt` was updated to reflect the latest official behavior.
+ `pgl` was updated to reflect the latest official behavior.
+ `fatal` was updated to reflect the latest official behavior.
+ Support was added for launching another game-which-has-too-many-files with romfs mods.
+ I rely on user reports for adding support/fixing these, and some of these games can be pretty obscure!
+ If you are affected by this, you will see "Data abort (0x101)" when trying to launch the game with mods.
+ Please reach out to `sciresm` on discord if this occurs to share your error report binary.
+ Although some games may be impossible to fix, I believe I can get almost everything working, so please let me try to help you (and improve atmosphère's support!) if you run into this!
+ General system stability improvements to enhance the user's experience.
## 1.9.5
+ Basic support was added for 20.5.0.
+ General system stability improvements to enhance the user's experience.
## 1.9.4
+ Basic support was added for 20.4.0. + Basic support was added for 20.4.0.
+ An issue was fixed in `exosphère`'s register accessilibity tables (thanks @CTCaer). + 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. + I believe this had no impact on official code, though it would have prevented some homebrew from interacting correctly with the MC0/MC1 registers.

6
emummc/.gitrepo vendored
View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/m4xw/emummc remote = https://github.com/m4xw/emummc
branch = develop branch = develop
commit = a8e5f1a184aeb8ba884166a1e4f386088d4a6cf1 commit = 3726bfd659600cdafd138277054568a3edba60a6
parent = 409c3cf9e190dbb65fe76570954939cbe8a5eca0 parent = 80bd459516e813fc6f10268ca31dd72a053a4ef3
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.9

2
emummc/README.md vendored
View File

@@ -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.1.0** **1.0.0 - 21.2.0**
## Features ## Features
* Arbitrary SDMMC backend selection * Arbitrary SDMMC backend selection

View File

@@ -79,6 +79,12 @@
#include "offsets/2000_exfat.h" #include "offsets/2000_exfat.h"
#include "offsets/2010.h" #include "offsets/2010.h"
#include "offsets/2010_exfat.h" #include "offsets/2010_exfat.h"
#include "offsets/2100.h"
#include "offsets/2100_exfat.h"
#include "offsets/2120.h"
#include "offsets/2120_exfat.h"
#include "offsets/2200.h"
#include "offsets/2200_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
@@ -169,6 +175,12 @@ DEFINE_OFFSET_STRUCT(_2000);
DEFINE_OFFSET_STRUCT(_2000_EXFAT); DEFINE_OFFSET_STRUCT(_2000_EXFAT);
DEFINE_OFFSET_STRUCT(_2010); DEFINE_OFFSET_STRUCT(_2010);
DEFINE_OFFSET_STRUCT(_2010_EXFAT); DEFINE_OFFSET_STRUCT(_2010_EXFAT);
DEFINE_OFFSET_STRUCT(_2100);
DEFINE_OFFSET_STRUCT(_2100_EXFAT);
DEFINE_OFFSET_STRUCT(_2120);
DEFINE_OFFSET_STRUCT(_2120_EXFAT);
DEFINE_OFFSET_STRUCT(_2200);
DEFINE_OFFSET_STRUCT(_2200_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) {
@@ -298,6 +310,18 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_2010)); return &(GET_OFFSET_STRUCT_NAME(_2010));
case FS_VER_20_1_0_EXFAT: case FS_VER_20_1_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT)); return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT));
case FS_VER_21_0_0:
return &(GET_OFFSET_STRUCT_NAME(_2100));
case FS_VER_21_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2100_EXFAT));
case FS_VER_21_2_0:
return &(GET_OFFSET_STRUCT_NAME(_2120));
case FS_VER_21_2_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2120_EXFAT));
case FS_VER_22_0_0:
return &(GET_OFFSET_STRUCT_NAME(_2200));
case FS_VER_22_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_2200_EXFAT));
default: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -116,6 +116,15 @@ enum FS_VER
FS_VER_20_1_0, FS_VER_20_1_0,
FS_VER_20_1_0_EXFAT, FS_VER_20_1_0_EXFAT,
FS_VER_21_0_0,
FS_VER_21_0_0_EXFAT,
FS_VER_21_2_0,
FS_VER_21_2_0_EXFAT,
FS_VER_22_0_0,
FS_VER_22_0_0_EXFAT,
FS_VER_MAX, FS_VER_MAX,
}; };

59
emummc/source/FS/offsets/2100.h vendored Normal file
View 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
View 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__

59
emummc/source/FS/offsets/2120.h vendored Normal file
View 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_2120_H__
#define __FS_2120_H__
// Accessor vtable getters
#define FS_OFFSET_2120_SDMMC_ACCESSOR_GC 0x1AC970
#define FS_OFFSET_2120_SDMMC_ACCESSOR_SD 0x1AE980
#define FS_OFFSET_2120_SDMMC_ACCESSOR_NAND 0x1ACFA0
// Hooks
#define FS_OFFSET_2120_SDMMC_WRAPPER_READ 0x1A8850
#define FS_OFFSET_2120_SDMMC_WRAPPER_WRITE 0x1A88B0
#define FS_OFFSET_2120_RTLD 0x2E1C0
#define FS_OFFSET_2120_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2120_CLKRST_SET_MIN_V_CLK_RATE 0x1CB9B0
// Misc funcs
#define FS_OFFSET_2120_LOCK_MUTEX 0x1A17D0
#define FS_OFFSET_2120_UNLOCK_MUTEX 0x1A1830
#define FS_OFFSET_2120_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A8810
#define FS_OFFSET_2120_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A8830
// Misc Data
#define FS_OFFSET_2120_SD_MUTEX 0xFEE408
#define FS_OFFSET_2120_NAND_MUTEX 0xFE9CF0
#define FS_OFFSET_2120_ACTIVE_PARTITION 0xFE9D30
#define FS_OFFSET_2120_SDMMC_DAS_HANDLE 0xFCBB18
// NOPs
#define FS_OFFSET_2120_SD_DAS_INIT 0x2B5C8
// Nintendo Paths
#define FS_OFFSET_2120_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000718CC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x000824F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008AF18, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A0B8C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2120_H__

59
emummc/source/FS/offsets/2120_exfat.h vendored Normal file
View 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_2120_EXFAT_EXFAT_H__
#define __FS_2120_EXFAT_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_GC 0x1B7AD0
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_SD 0x1B9AE0
#define FS_OFFSET_2120_EXFAT_SDMMC_ACCESSOR_NAND 0x1B8100
// Hooks
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_READ 0x1B39B0
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_WRITE 0x1B3A10
#define FS_OFFSET_2120_EXFAT_RTLD 0x2E1C0
#define FS_OFFSET_2120_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2120_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D6B10
// Misc funcs
#define FS_OFFSET_2120_EXFAT_LOCK_MUTEX 0x1AC930
#define FS_OFFSET_2120_EXFAT_UNLOCK_MUTEX 0x1AC990
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B3970
#define FS_OFFSET_2120_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1B3990
// Misc Data
#define FS_OFFSET_2120_EXFAT_SD_MUTEX 0xFFF408
#define FS_OFFSET_2120_EXFAT_NAND_MUTEX 0xFFACF0
#define FS_OFFSET_2120_EXFAT_ACTIVE_PARTITION 0xFFAD30
#define FS_OFFSET_2120_EXFAT_SDMMC_DAS_HANDLE 0xFD8B18
// NOPs
#define FS_OFFSET_2120_EXFAT_SD_DAS_INIT 0x2B5C8
// Nintendo Paths
#define FS_OFFSET_2120_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000718CC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x000824F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008AF18, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A0B8C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2120_EXFAT_EXFAT_H__

59
emummc/source/FS/offsets/2200.h vendored Normal file
View 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_2200_H__
#define __FS_2200_H__
// Accessor vtable getters
#define FS_OFFSET_2200_SDMMC_ACCESSOR_GC 0x1B01C0
#define FS_OFFSET_2200_SDMMC_ACCESSOR_SD 0x1B21C0
#define FS_OFFSET_2200_SDMMC_ACCESSOR_NAND 0x1B07F0
// Hooks
#define FS_OFFSET_2200_SDMMC_WRAPPER_READ 0x1AC0F0
#define FS_OFFSET_2200_SDMMC_WRAPPER_WRITE 0x1AC150
#define FS_OFFSET_2200_RTLD 0x2DED0
#define FS_OFFSET_2200_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2200_CLKRST_SET_MIN_V_CLK_RATE 0x1CF260
// Misc funcs
#define FS_OFFSET_2200_LOCK_MUTEX 0x1A4EF0
#define FS_OFFSET_2200_UNLOCK_MUTEX 0x1A4F40
#define FS_OFFSET_2200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AC0B0
#define FS_OFFSET_2200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AC0D0
// Misc Data
#define FS_OFFSET_2200_SD_MUTEX 0xFF1408
#define FS_OFFSET_2200_NAND_MUTEX 0xFECD00
#define FS_OFFSET_2200_ACTIVE_PARTITION 0xFECD40
#define FS_OFFSET_2200_SDMMC_DAS_HANDLE 0xFCEB98
// NOPs
#define FS_OFFSET_2200_SD_DAS_INIT 0x2B438
// Nintendo Paths
#define FS_OFFSET_2200_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000715EC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00082E64, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008B888, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A1B1C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2200_H__

59
emummc/source/FS/offsets/2200_exfat.h vendored Normal file
View 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_2200_EXFAT_H__
#define __FS_2200_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_2200_EXFAT_SDMMC_ACCESSOR_GC 0x1BB3B0
#define FS_OFFSET_2200_EXFAT_SDMMC_ACCESSOR_SD 0x1BD3B0
#define FS_OFFSET_2200_EXFAT_SDMMC_ACCESSOR_NAND 0x1BB9E0
// Hooks
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_READ 0x1B72E0
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_WRITE 0x1B7340
#define FS_OFFSET_2200_EXFAT_RTLD 0x2DED0
#define FS_OFFSET_2200_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C)))
#define FS_OFFSET_2200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1DA450
// Misc funcs
#define FS_OFFSET_2200_EXFAT_LOCK_MUTEX 0x1B00E0
#define FS_OFFSET_2200_EXFAT_UNLOCK_MUTEX 0x1B0130
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B72A0
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1B72C0
// Misc Data
#define FS_OFFSET_2200_EXFAT_SD_MUTEX 0x1002408
#define FS_OFFSET_2200_EXFAT_NAND_MUTEX 0xFFDD00
#define FS_OFFSET_2200_EXFAT_ACTIVE_PARTITION 0xFFDD40
#define FS_OFFSET_2200_EXFAT_SDMMC_DAS_HANDLE 0xFDBB98
// NOPs
#define FS_OFFSET_2200_EXFAT_SD_DAS_INIT 0x2B438
// Nintendo Paths
#define FS_OFFSET_2200_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x000715EC, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00082E64, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008B888, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x000A1B1C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_2200_EXFAT_H__

View File

@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* 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 0x2E, 0x27, 0x44, 0xEA, 0x32, 0xF8, 0x2C, 0xF0, 0x6F, 0xCA, 0xCD, 0x77, 0xAE, 0xAE, 0x1A, 0x1B
/* 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 0x82, 0xE2, 0x0A, 0x59, 0x67, 0xDF, 0xBF, 0x51, 0x47, 0x62, 0x11, 0xF2, 0x41, 0xD3, 0xEE, 0x13
/* 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,8 @@ _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. */
.byte 0x97, 0xB3, 0x61, 0x88, 0x5C, 0x0D, 0xA1, 0x38, 0x73, 0xA4, 0x2F, 0x1A, 0x46, 0xA1, 0x09, 0xBF /* Master key 14 encrypted with Master key 15. */
/* 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 +135,8 @@ _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. */
.byte 0x14, 0xCB, 0x60, 0x29, 0x3D, 0xE0, 0xFB, 0xF2, 0x5B, 0x60, 0xB6, 0xC5, 0x2E, 0x77, 0x8F, 0x98 /* Master key 14 encrypted with Master key 15. */
/* 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 +156,8 @@ _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. */
.byte 0xF8, 0xF4, 0x22, 0xA4, 0x34, 0xAE, 0x0E, 0x0C, 0x4D, 0x5C, 0x5B, 0xA1, 0x1B, 0x46, 0x1C, 0x78 /* 22.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 +177,8 @@ _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. */
.byte 0xF3, 0xBC, 0xB5, 0xB5, 0x5F, 0x01, 0x50, 0x2B, 0x69, 0x69, 0x3A, 0x6B, 0xF9, 0x2C, 0x11, 0x9F /* 22.0.0 Device Master Kek Source. */
/* Production Device Master Kek Sources. */ /* Production Device Master Kek Sources. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
@@ -189,4 +197,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ .byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */
.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */ .byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */
.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */ .byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */
.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */ .byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */
.byte 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 /* 21.0.0 Device Master Kek Source. */
.byte 0xC4, 0x6F, 0x0E, 0x72, 0x43, 0xCE, 0x87, 0xFC, 0x38, 0x95, 0x9B, 0xC9, 0x31, 0x44, 0x97, 0x63 /* 22.0.0 Device Master Kek Source. */

View File

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

View File

@@ -132,10 +132,13 @@ namespace ams::secmon::smc {
} }
u32 GetMemoryMode() { u32 GetMemoryMode() {
/* Unless development function is enabled, we're 4 GB. */ /* Unless development function or forced boot config memory size is enabled, we're 4 GB. */
u32 memory_mode = pkg1::MemoryMode_4GB; u32 memory_mode = pkg1::MemoryMode_4GB;
if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) { const auto &bcd = GetBootConfig().data;
const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */
if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) {
memory_mode = GetMemoryMode(bcd.GetMemoryMode()); memory_mode = GetMemoryMode(bcd.GetMemoryMode());
} }
@@ -146,17 +149,19 @@ namespace ams::secmon::smc {
pkg1::MemorySize memory_size = pkg1::MemorySize_4GB; pkg1::MemorySize memory_size = pkg1::MemorySize_4GB;
util::BitPack32 value = {}; util::BitPack32 value = {};
if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) { const auto &bcd = GetBootConfig().data;
memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode())); const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */
if (bcd.IsDevelopmentFunctionEnabled()) {
value.Set<KernelConfiguration::Flags1>(bcd.GetKernelFlags1()); value.Set<KernelConfiguration::Flags1>(bcd.GetKernelFlags1());
value.Set<KernelConfiguration::Flags0>(bcd.GetKernelFlags0()); value.Set<KernelConfiguration::Flags0>(bcd.GetKernelFlags0());
} }
value.Set<KernelConfiguration::PhysicalMemorySize>(memory_size); if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) {
memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode()));
}
/* Exosphere extensions. */ value.Set<KernelConfiguration::PhysicalMemorySize>(memory_size);
const auto &sc = GetSecmonConfiguration();
if (!sc.DisableUserModeExceptionHandlers()) { if (!sc.DisableUserModeExceptionHandlers()) {
value.Set<KernelConfiguration::EnableUserExceptionHandlers>(true); value.Set<KernelConfiguration::EnableUserExceptionHandlers>(true);
@@ -169,6 +174,27 @@ namespace ams::secmon::smc {
return value.value; return value.value;
} }
fuse::DramId GetDramIdAdjusted() {
const auto dram_id = fuse::GetDramId();
AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count);
const auto fuse_mem_size = DramIdToMemorySize[dram_id];
const auto phys_mem_size = GetPhysicalMemorySize();
AMS_ABORT_UNLESS(fuse_mem_size <= phys_mem_size);
if (fuse_mem_size == phys_mem_size) {
return dram_id;
}
/* Adjust Dram ID to match density/ranks. */
if (GetSocType() == fuse::SocType_Erista) {
return fuse::DramId_IcosaSamsung6GB;
} else { /* fuse::SocType_Mariko */
return fuse::DramId_IowaSamsung1y8GBX;
}
}
constinit u64 g_payload_address = 0; constinit u64 g_payload_address = 0;
constinit bool g_set_true_target_firmware = false; constinit bool g_set_true_target_firmware = false;
@@ -178,7 +204,7 @@ namespace ams::secmon::smc {
args.r[1] = GetBootConfig().signed_data.IsProgramVerificationDisabled(); args.r[1] = GetBootConfig().signed_data.IsProgramVerificationDisabled();
break; break;
case ConfigItem::DramId: case ConfigItem::DramId:
args.r[1] = fuse::GetDramId(); args.r[1] = GetDramIdAdjusted(); /* Nintendo: fuse::GetDramId() */
break; break;
case ConfigItem::SecurityEngineInterruptNumber: case ConfigItem::SecurityEngineInterruptNumber:
args.r[1] = SecurityEngineUserInterruptId; args.r[1] = SecurityEngineUserInterruptId;
@@ -471,9 +497,18 @@ namespace ams::secmon::smc {
/* For exosphere's usage. */ /* For exosphere's usage. */
pkg1::MemorySize GetPhysicalMemorySize() { pkg1::MemorySize GetPhysicalMemorySize() {
const auto dram_id = fuse::GetDramId(); const uintptr_t MC = secmon::MemoryRegionVirtualDeviceMemoryController.GetAddress();
AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count); const u32 mem_size = reg::Read(MC + MC_EMEM_CFG) & 0x3FFF;
return DramIdToMemorySize[dram_id];
switch (mem_size >> 10) {
case 4:
default:
return pkg1::MemorySize_4GB;
case 6:
return pkg1::MemorySize_6GB;
case 8:
return pkg1::MemorySize_8GB;
}
} }
} }

View File

@@ -602,7 +602,7 @@ namespace ams::nxboot {
Print("\n"); Print("\n");
if (R_SUCCEEDED(save_result)) { if (R_SUCCEEDED(save_result)) {
Print("Report saved to /atmosphere/fatal_errors/report_%016" PRIx64 ".bin", f_ctx->report_identifier); Print("Report saved to /atmosphere/fatal_errors/report_%016" PRIx64 ".bin\n", f_ctx->report_identifier);
} else { } else {
Print("Failed to save report to the SD card! (%08" PRIx32 ")\n", save_result.GetValue()); Print("Failed to save report to the SD card! (%08" PRIx32 ")\n", save_result.GetValue());
} }

View File

@@ -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 0x82, 0xE2, 0x0A, 0x59, 0x67, 0xDF, 0xBF, 0x51, 0x47, 0x62, 0x11, 0xF2, 0x41, 0xD3, 0xEE, 0x13
}; };
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 0x2E, 0x27, 0x44, 0xEA, 0x32, 0xF8, 0x2C, 0xF0, 0x6F, 0xCA, 0xCD, 0x77, 0xAE, 0xAE, 0x1A, 0x1B
}; };
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 0x15, 0xAC, 0x96, 0x34, 0xF5, 0x32, 0x56, 0x68, 0xFE, 0x5B, 0x9D, 0xD7, 0xED, 0x19, 0xB7, 0x8E
}; };
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
@@ -74,6 +74,8 @@ 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. */
{ 0xF8, 0xF4, 0x22, 0xA4, 0x34, 0xAE, 0x0E, 0x0C, 0x4D, 0x5C, 0x5B, 0xA1, 0x1B, 0x46, 0x1C, 0x78 }, /* 22.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 +96,8 @@ 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. */
{ 0xC4, 0x6F, 0x0E, 0x72, 0x43, 0xCE, 0x87, 0xFC, 0x38, 0x95, 0x9B, 0xC9, 0x31, 0x44, 0x97, 0x63 }, /* 22.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 +118,8 @@ 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. */
{ 0xF3, 0xBC, 0xB5, 0xB5, 0x5F, 0x01, 0x50, 0x2B, 0x69, 0x69, 0x3A, 0x6B, 0xF9, 0x2C, 0x11, 0x9F }, /* 22.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 +143,8 @@ 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. */
{ 0x14, 0xCB, 0x60, 0x29, 0x3D, 0xE0, 0xFB, 0xF2, 0x5B, 0x60, 0xB6, 0xC5, 0x2E, 0x77, 0x8F, 0x98 }, /* Master key 14 encrypted with Master key 15. */
}; };
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 +168,8 @@ 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. */
{ 0x97, 0xB3, 0x61, 0x88, 0x5C, 0x0D, 0xA1, 0x38, 0x73, 0xA4, 0x2F, 0x1A, 0x46, 0xA1, 0x09, 0xBF }, /* Master key 14 encrypted with Master key 15. */
}; };
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};

View File

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

View File

@@ -265,6 +265,10 @@ 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;
} else if (std::memcmp(package1 + 0x10, "20260123", 8) == 0) {
return ams::TargetFirmware_22_0_0;
} }
break; break;
default: default:
@@ -409,8 +413,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;
@@ -540,6 +545,12 @@ namespace ams::nxboot {
} else { } else {
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess; storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess;
} }
} else if (std::strcmp(entry.key, "enable_mem_mode") == 0) {
if (entry.value[0] == '1') {
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled;
} else {
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled;
}
} else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) { } else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) {
if (!emummc_enabled) { if (!emummc_enabled) {
if (entry.value[0] == '1') { if (entry.value[0] == '1') {

View File

@@ -186,6 +186,15 @@ namespace ams::nxboot {
FsVersion_20_1_0, FsVersion_20_1_0,
FsVersion_20_1_0_Exfat, FsVersion_20_1_0_Exfat,
FsVersion_21_0_0,
FsVersion_21_0_0_Exfat,
FsVersion_21_2_0,
FsVersion_21_2_0_Exfat,
FsVersion_22_0_0,
FsVersion_22_0_0_Exfat,
FsVersion_Count, FsVersion_Count,
}; };
@@ -284,6 +293,15 @@ namespace ams::nxboot {
{ 0xED, 0x34, 0xB4, 0x50, 0x58, 0x4A, 0x5B, 0x43 }, /* FsVersion_20_1_0 */ { 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 */ { 0xA5, 0x1A, 0xA4, 0x92, 0x6C, 0x41, 0x87, 0x59 }, /* FsVersion_20_1_0_Exfat */
{ 0xEE, 0x4B, 0x30, 0x12, 0xA6, 0x84, 0x02, 0x25 }, /* FsVersion_21_0_0 */
{ 0x6E, 0x2B, 0xD9, 0xBA, 0xA3, 0xB9, 0x10, 0xF1 }, /* FsVersion_21_0_0_Exfat */
{ 0xAF, 0x1D, 0xBD, 0xC7, 0x82, 0x98, 0x3C, 0xBD }, /* FsVersion_21_2_0 */
{ 0x56, 0x25, 0x17, 0xA1, 0x92, 0xC3, 0xC8, 0xF0 }, /* FsVersion_21_2_0_Exfat */
{ 0xB7, 0xA2, 0x97, 0x39, 0xB7, 0xED, 0xDE, 0xFC }, /* FsVersion_22_0_0 */
{ 0xFB, 0x0B, 0x68, 0xDB, 0x24, 0x03, 0xD1, 0x19 }, /* FsVersion_22_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) {
@@ -685,6 +703,28 @@ namespace ams::nxboot {
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:
case FsVersion_21_2_0:
AddPatch(fs_meta, 0x1AC9ED, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1ACA05, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x17FBE0, NogcPatch1, sizeof(NogcPatch1));
break;
case FsVersion_21_0_0_Exfat:
case FsVersion_21_2_0_Exfat:
AddPatch(fs_meta, 0x1B7B4D, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1B7B65, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x18AD40, NogcPatch1, sizeof(NogcPatch1));
break;
case FsVersion_22_0_0:
AddPatch(fs_meta, 0x1B023D, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1B0255, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x183060, NogcPatch1, sizeof(NogcPatch1));
break;
case FsVersion_22_0_0_Exfat:
AddPatch(fs_meta, 0x1BB42D, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x1BB445, NogcPatch0, sizeof(NogcPatch0));
AddPatch(fs_meta, 0x18E250, NogcPatch1, sizeof(NogcPatch1));
break;
default: default:
break; break;
} }

View File

@@ -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 = bbd085442eb240f400ab26bd808ad18c42ceb103 commit = 82f1553c4c7e68364f7e630b1c68f2aee8681dee
parent = 98bc030b37a24b76a130b418f846d2dabc47bf27 parent = 252f8685b493d0dfd428e9439b0296109776b935
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.9

View File

@@ -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)

View File

@@ -40,6 +40,8 @@ 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_22_0_0 = 0x15,
KeyGeneration_Count, KeyGeneration_Count,

View File

@@ -30,6 +30,7 @@ namespace ams::secmon {
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5), SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6), SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7), SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled = (1u << 8),
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel, SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
}; };
@@ -103,6 +104,7 @@ namespace ams::secmon {
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; } constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; } constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; } constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
constexpr bool IsBootConfigMemoryModeEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled) != 0; }
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); } constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
}; };

View File

@@ -177,6 +177,8 @@ namespace ams::fuse {
} }
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_22_0_0,
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,

View File

@@ -83,9 +83,9 @@ namespace ams::kern::arch::arm64 {
} }
NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level); NOINLINE 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;

View File

@@ -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. */

View File

@@ -165,7 +165,7 @@ namespace ams::kern::arch::arm64 {
constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_fpcr(), m_fpsr(), m_callee_saved_fpu(), m_locked() { /* ... */ } 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);

View File

@@ -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) {

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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);
}; };

View File

@@ -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; }
}; };

View File

@@ -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>

View File

@@ -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; }

View File

@@ -200,6 +200,7 @@ namespace ams::kern {
bool m_is_kernel; bool m_is_kernel;
bool m_enable_aslr; bool m_enable_aslr;
bool m_enable_device_address_space_merge; bool m_enable_device_address_space_merge;
bool m_allowed_exec_device_mapping;
KMemoryBlockSlabManager *m_memory_block_slab_manager; KMemoryBlockSlabManager *m_memory_block_slab_manager;
KBlockInfoManager *m_block_info_manager; KBlockInfoManager *m_block_info_manager;
KResourceLimit *m_resource_limit; KResourceLimit *m_resource_limit;
@@ -217,7 +218,7 @@ namespace ams::kern {
m_alias_code_region_end(Null<KProcessAddress>), m_code_region_start(Null<KProcessAddress>), m_code_region_end(Null<KProcessAddress>), m_alias_code_region_end(Null<KProcessAddress>), m_code_region_start(Null<KProcessAddress>), m_code_region_end(Null<KProcessAddress>),
m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_alias_region_extra_size(), m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_alias_region_extra_size(),
m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize),
m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_allowed_exec_device_mapping(),
m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(), m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(),
m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value() m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value()
{ {
@@ -226,7 +227,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();
@@ -520,6 +521,8 @@ namespace ams::kern {
size_t GetAliasCodeDataSize() const; size_t GetAliasCodeDataSize() const;
u32 GetAllocateOption() const { return m_allocate_option; } u32 GetAllocateOption() const { return m_allocate_option; }
void AllowDeviceMappingOfExecPages() { m_allowed_exec_device_mapping = true; }
public: public:
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) { static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {
return KMemoryLayout::GetLinearVirtualAddress(addr); return KMemoryLayout::GetLinearVirtualAddress(addr);

View File

@@ -102,8 +102,8 @@ namespace ams::kern {
IoRegionList m_io_region_list; IoRegionList m_io_region_list;
bool m_is_suspended; bool m_is_suspended;
bool m_is_immortal; bool m_is_immortal;
bool m_is_jit_debug;
bool m_is_handle_table_initialized; bool m_is_handle_table_initialized;
bool m_is_jit_debug;
ams::svc::DebugEvent m_jit_debug_event_type; ams::svc::DebugEvent m_jit_debug_event_type;
ams::svc::DebugException m_jit_debug_exception_type; ams::svc::DebugException m_jit_debug_exception_type;
uintptr_t m_jit_debug_params[4]; uintptr_t m_jit_debug_params[4];
@@ -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; }

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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);

View File

@@ -215,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 {
@@ -508,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
} }

View File

@@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue())); 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() {

View File

@@ -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();
} }
} }

View File

@@ -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));
} }
} }

View File

@@ -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) {

View File

@@ -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

View File

@@ -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]))));

View File

@@ -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());
} }
} }

View File

@@ -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() {

View File

@@ -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));
@@ -287,7 +285,7 @@ namespace ams::kern {
MESOSPHERE_INIT_ABORT_UNLESS(expected_size != 0); MESOSPHERE_INIT_ABORT_UNLESS(expected_size != 0);
/* Ensure that the size we need to reserve is as we expect it to be. */ /* Ensure that the size we need to reserve is as we expect it to be. */
const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize); const u32 total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize);
MESOSPHERE_ABORT_UNLESS(total_size == expected_size); MESOSPHERE_ABORT_UNLESS(total_size == expected_size);
MESOSPHERE_ABORT_UNLESS(total_size <= InitialProcessBinarySizeMax); MESOSPHERE_ABORT_UNLESS(total_size <= InitialProcessBinarySizeMax);

View File

@@ -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. */

View File

@@ -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());
} }

View File

@@ -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();
} }
} }

View File

@@ -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() {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {
@@ -211,6 +211,7 @@ namespace ams::kern {
/* Set other basic fields. */ /* Set other basic fields. */
m_enable_aslr = (flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; m_enable_aslr = (flags & ams::svc::CreateProcessFlag_EnableAslr) != 0;
m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0;
m_allowed_exec_device_mapping = false;
m_address_space_start = start; m_address_space_start = start;
m_address_space_end = end; m_address_space_end = end;
m_is_kernel = false; m_is_kernel = false;
@@ -1792,7 +1793,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 +2666,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 +2689,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 +2767,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 +2777,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 +2852,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 +2862,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();
@@ -3079,7 +3078,9 @@ namespace ams::kern {
const u32 test_state = (is_aligned ? KMemoryState_FlagCanAlignedDeviceMap : KMemoryState_FlagCanDeviceMap) | (check_heap ? KMemoryState_FlagReferenceCounted : KMemoryState_None); const u32 test_state = (is_aligned ? KMemoryState_FlagCanAlignedDeviceMap : KMemoryState_FlagCanDeviceMap) | (check_heap ? KMemoryState_FlagReferenceCounted : KMemoryState_None);
size_t num_allocator_blocks; size_t num_allocator_blocks;
KMemoryState old_state; KMemoryState old_state;
R_TRY(this->CheckMemoryState(std::addressof(old_state), nullptr, nullptr, std::addressof(num_allocator_blocks), address, size, test_state, test_state, perm, perm, KMemoryAttribute_IpcLocked | KMemoryAttribute_Locked, KMemoryAttribute_None, KMemoryAttribute_DeviceShared)); const KMemoryPermission perm_mask = static_cast<KMemoryPermission>(perm | (m_allowed_exec_device_mapping ? KMemoryPermission_None : KMemoryPermission_UserExecute));
R_TRY(this->CheckMemoryState(std::addressof(old_state), nullptr, nullptr, std::addressof(num_allocator_blocks), address, size, test_state, test_state, perm_mask, perm, KMemoryAttribute_IpcLocked | KMemoryAttribute_Locked, KMemoryAttribute_None, KMemoryAttribute_DeviceShared));
/* Create an update allocator. */ /* Create an update allocator. */
Result allocator_result; Result allocator_result;

View File

@@ -185,6 +185,11 @@ namespace ams::kern {
/* Validate that the intended kernel version isn't too high for us to support. */ /* Validate that the intended kernel version isn't too high for us to support. */
R_UNLESS(m_capabilities.GetIntendedKernelVersion() <= ams::svc::SupportedKernelVersion, svc::ResultInvalidCombination()); R_UNLESS(m_capabilities.GetIntendedKernelVersion() <= ams::svc::SupportedKernelVersion, svc::ResultInvalidCombination());
/* Enable mapping device pages as executable on legacy processes. */
if (m_capabilities.GetIntendedKernelMajorVersion() < 26) {
m_page_table.GetBasePageTable().AllowDeviceMappingOfExecPages();
}
/* Create and clear the process local region. */ /* Create and clear the process local region. */
R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address))); R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address)));
m_plr_heap_address = this->GetThreadLocalRegionPointer(m_plr_address); m_plr_heap_address = this->GetThreadLocalRegionPointer(m_plr_address);
@@ -404,7 +409,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 +425,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 +476,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 +512,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 +674,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 +686,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 +718,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 +773,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());
} }
} }
@@ -975,6 +981,9 @@ namespace ams::kern {
/* Set the thread arguments. */ /* Set the thread arguments. */
main_thread->GetContext().SetArguments(0, thread_handle); main_thread->GetContext().SetArguments(0, thread_handle);
/* Pass the thread handle to the thread local region. */
static_cast<ams::svc::ThreadLocalRegion *>(main_thread->GetThreadLocalRegionHeapAddress())->thread_handle = thread_handle;
/* Update our state. */ /* Update our state. */
this->ChangeState((state == State_Created) ? State_Running : State_RunningAttached); this->ChangeState((state == State_Created) ? State_Running : State_RunningAttached);
ON_RESULT_FAILURE_2 { this->ChangeState(state); }; ON_RESULT_FAILURE_2 { this->ChangeState(state); };

View File

@@ -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() {

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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);

View File

@@ -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) {

View File

@@ -32,7 +32,7 @@ namespace ams::kern {
R_RETURN(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, page_buf->GetPhysicalAddress(), KMemoryState_ThreadLocal, KMemoryPermission_UserReadWrite)); 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() {

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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));

View File

@@ -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();
} }
} }

View File

@@ -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);

View File

@@ -66,6 +66,9 @@ namespace ams::kern::svc {
/* Add the thread to the handle table. */ /* Add the thread to the handle table. */
R_TRY(process.GetHandleTable().Add(out, thread)); R_TRY(process.GetHandleTable().Add(out, thread));
/* Pass the thread handle to the thread local region. */
static_cast<ams::svc::ThreadLocalRegion *>(thread->GetThreadLocalRegionHeapAddress())->thread_handle = *out;
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -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 ) \
@@ -653,7 +661,7 @@
HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ControllerStyleListDeprecated, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, 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 ) \
@@ -927,6 +935,50 @@
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(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(BluetoothHaltedHciCommandOpcode, 775, ErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
HANDLER(AcpSupportedLanguageFlagForNxAddon, 776, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(FsSaveDataFileSystemPeakMountCount, 777, FsProxyErrorInfo3, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(TestBool, 778, Test, FieldType_Bool, FieldFlag_None ) \
HANDLER(TestI8Array, 779, Test, FieldType_I8Array, 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 ) \
@@ -961,4 +1013,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 ) \
HANDLER(ControllerStyleList, 1035, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None )

View File

@@ -23,7 +23,7 @@ namespace ams::erpt {
#define GENERATE_ENUM(NAME, ID, ...) NAME = ID, #define GENERATE_ENUM(NAME, ID, ...) NAME = ID,
enum FieldType { enum FieldType: u8 {
AMS_ERPT_FOREACH_FIELD_TYPE(GENERATE_ENUM) AMS_ERPT_FOREACH_FIELD_TYPE(GENERATE_ENUM)
FieldType_Count, FieldType_Count,
}; };
@@ -111,6 +111,7 @@ namespace ams::erpt {
struct CreateReportOptionFlag { struct CreateReportOptionFlag {
using SubmitFsInfo = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<0>; using SubmitFsInfo = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<0>;
using Unknown0x20000 = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<17>; /* TODO: What is this, it's checked in Reporter::CreateReport or below */
}; };
using CreateReportOptionFlagSet = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>; using CreateReportOptionFlagSet = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>;
@@ -194,6 +195,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;
@@ -237,4 +244,33 @@ namespace ams::erpt {
Map16 = 0xDE, Map16 = 0xDE,
}; };
constexpr inline u32 ErrorCodeSizeMax = 15;
constexpr inline u32 ProgramIdSizeMax = 17;
struct NotifiableErrorCodeReportEntry {
char error_code[ErrorCodeSizeMax];
char program_id[ProgramIdSizeMax];
u8 is_visible;
u8 is_system_abort;
u8 is_application_abort;
};
static_assert(sizeof(NotifiableErrorCodeReportEntry) == 35);
struct NotifiableErrorCodesData : public sf::LargeData, public sf::PrefersAutoSelectTransferMode {
u32 entry_count;
NotifiableErrorCodeReportEntry entries[50];
char firmware_display_version[0x18];
char private_os_version[96];
char product_model[16];
char region_code[34];
};
static_assert(sizeof(NotifiableErrorCodesData) == 0x784);
struct SystemInfo {
char os_version[0x18];
char private_os_version[96];
char product_model[16];
const char *region;
};
} }

View File

@@ -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)

View File

@@ -25,6 +25,7 @@
AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out<erpt::StorageUsageStatistics> out), (out), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out<erpt::StorageUsageStatistics> out), (out), hos::Version_5_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentListDeprecated, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0, hos::Version_19_0_1) \ AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentListDeprecated, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0, hos::Version_19_0_1) \
AMS_SF_METHOD_INFO(C, H, 6, Result, GetAttachmentList, (ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_count, out_buf, report_id), hos::Version_20_0_0) \ AMS_SF_METHOD_INFO(C, H, 6, Result, GetAttachmentList, (ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_count, out_buf, report_id), hos::Version_20_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, PopNotifiableErrorCodes, (ams::sf::Out<erpt::NotifiableErrorCodesData> out), (out), hos::Version_22_0_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, GetReportSizeMax, (ams::sf::Out<u32> out), (out), hos::Version_20_0_0) AMS_SF_METHOD_INFO(C, H, 10, Result, GetReportSizeMax, (ams::sf::Out<u32> out), (out), hos::Version_20_0_0)

View File

@@ -21,7 +21,9 @@ namespace ams::erpt::srv {
Result Initialize(u8 *mem, size_t mem_size); Result Initialize(u8 *mem, size_t mem_size);
Result InitializeAndStartService(); Result InitializeAndStartService();
Result SetSerialNumberAndOsVersion(const char *sn, u32 sn_len, const char *os, u32 os_len, const char *os_priv, u32 os_priv_len); const SystemInfo &GetSystemInfo();
Result SetSerialNumber(const char *sn, u32 sn_len);
Result SetProductModel(const char *model, u32 model_len); Result SetProductModel(const char *model, u32 model_len);
Result SetRegionSetting(const char *region, u32 region_len); Result SetRegionSetting(const char *region, u32 region_len);

View File

@@ -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());

View File

@@ -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()
{ {

View File

@@ -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)

View File

@@ -52,7 +52,8 @@ namespace ams::fs {
struct GameCardErrorReportInfo { struct GameCardErrorReportInfo {
u16 game_card_crc_error_num; u16 game_card_crc_error_num;
u16 reserved1; u8 last_deactivate_reason;
u8 reserved1;
u16 asic_crc_error_num; u16 asic_crc_error_num;
u16 reserved2; u16 reserved2;
u16 refresh_num; u16 refresh_num;
@@ -73,7 +74,8 @@ namespace ams::fs {
u32 awaken_count; u32 awaken_count;
u32 read_count_from_insert; u32 read_count_from_insert;
u32 read_count_from_awaken; u32 read_count_from_awaken;
u8 reserved5[8]; u32 last_deactivate_reason_result;
u32 reserved5;
}; };
static_assert(util::is_pod<GameCardErrorReportInfo>::value); static_assert(util::is_pod<GameCardErrorReportInfo>::value);
static_assert(sizeof(GameCardErrorReportInfo) == 0x40); static_assert(sizeof(GameCardErrorReportInfo) == 0x40);

View File

@@ -132,7 +132,7 @@
AMS_SF_METHOD_INFO(C, H, 1000, Result, SetBisRootForHost, (u32 id, const fssrv::sf::FspPath &path), (id, path), hos::Version_Min, hos::Version_9_2_0) \ AMS_SF_METHOD_INFO(C, H, 1000, Result, SetBisRootForHost, (u32 id, const fssrv::sf::FspPath &path), (id, path), hos::Version_Min, hos::Version_9_2_0) \
AMS_SF_METHOD_INFO(C, H, 1001, Result, SetSaveDataSize, (s64 size, s64 journal_size), (size, journal_size)) \ AMS_SF_METHOD_INFO(C, H, 1001, Result, SetSaveDataSize, (s64 size, s64 journal_size), (size, journal_size)) \
AMS_SF_METHOD_INFO(C, H, 1002, Result, SetSaveDataRootPath, (const fssrv::sf::FspPath &path), (path)) \ AMS_SF_METHOD_INFO(C, H, 1002, Result, SetSaveDataRootPath, (const fssrv::sf::FspPath &path), (path)) \
AMS_SF_METHOD_INFO(C, H, 1003, Result, DisableAutoSaveDataCreation, (), ()) \ AMS_SF_METHOD_INFO(C, H, 1003, Result, DisableAutoSaveDataCreation, (), (), hos::Version_Min, hos::Version_21_2_0) \
AMS_SF_METHOD_INFO(C, H, 1004, Result, SetGlobalAccessLogMode, (u32 mode), (mode)) \ AMS_SF_METHOD_INFO(C, H, 1004, Result, SetGlobalAccessLogMode, (u32 mode), (mode)) \
AMS_SF_METHOD_INFO(C, H, 1005, Result, GetGlobalAccessLogMode, (ams::sf::Out<u32> out), (out)) \ AMS_SF_METHOD_INFO(C, H, 1005, Result, GetGlobalAccessLogMode, (ams::sf::Out<u32> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 1006, Result, OutputAccessLogToSdCard, (const ams::sf::InBuffer &buf), (buf)) \ AMS_SF_METHOD_INFO(C, H, 1006, Result, OutputAccessLogToSdCard, (const ams::sf::InBuffer &buf), (buf)) \

View File

@@ -95,6 +95,13 @@ namespace ams::hos {
Version_20_2_0 = ::ams::TargetFirmware_20_2_0, Version_20_2_0 = ::ams::TargetFirmware_20_2_0,
Version_20_3_0 = ::ams::TargetFirmware_20_3_0, Version_20_3_0 = ::ams::TargetFirmware_20_3_0,
Version_20_4_0 = ::ams::TargetFirmware_20_4_0, Version_20_4_0 = ::ams::TargetFirmware_20_4_0,
Version_20_5_0 = ::ams::TargetFirmware_20_5_0,
Version_21_0_0 = ::ams::TargetFirmware_21_0_0,
Version_21_0_1 = ::ams::TargetFirmware_21_0_1,
Version_21_1_0 = ::ams::TargetFirmware_21_1_0,
Version_21_2_0 = ::ams::TargetFirmware_21_2_0,
Version_22_0_0 = ::ams::TargetFirmware_22_0_0,
Version_22_1_0 = ::ams::TargetFirmware_22_1_0,
Version_Current = ::ams::TargetFirmware_Current, Version_Current = ::ams::TargetFirmware_Current,

View File

@@ -94,12 +94,14 @@ 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),
Flag_UseZbicCompression = (1 << 7),
}; };
struct SegmentInfo { struct SegmentInfo {
@@ -180,6 +182,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 {

View File

@@ -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)));

View File

@@ -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);

View File

@@ -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)

View File

@@ -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>);

View File

@@ -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)

View File

@@ -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);
} }

View File

@@ -388,7 +388,7 @@
} }
ALWAYS_INLINE Result GetDebugEvent(::ams::svc::UserPointer< ::ams::svc::lp64::DebugEventInfo *> out_info, ::ams::svc::Handle debug_handle) { ALWAYS_INLINE Result GetDebugEvent(::ams::svc::UserPointer< ::ams::svc::lp64::DebugEventInfo *> out_info, ::ams::svc::Handle debug_handle) {
R_RETURN(::svcGetDebugEvent(out_info.GetPointerUnsafe(), debug_handle)); R_RETURN(::svcGetDebugEvent(reinterpret_cast<::DebugEventInfo *>(out_info.GetPointerUnsafe()), debug_handle));
} }
ALWAYS_INLINE Result ContinueDebugEvent(::ams::svc::Handle debug_handle, uint32_t flags, ::ams::svc::UserPointer<const uint64_t *> thread_ids, int32_t num_thread_ids) { ALWAYS_INLINE Result ContinueDebugEvent(::ams::svc::Handle debug_handle, uint32_t flags, ::ams::svc::UserPointer<const uint64_t *> thread_ids, int32_t num_thread_ids) {

View File

@@ -21,8 +21,11 @@ namespace ams::util {
/* Compression utilities. */ /* Compression utilities. */
int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size); int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
size_t CompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size);
/* Decompression utilities. */ /* Decompression utilities. */
int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size); int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
size_t DecompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size);
bool DecompressZstdForLoader(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size);
} }

View File

@@ -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)

View File

@@ -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));
} }
} }

View File

@@ -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;
} }
} }

View File

@@ -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));

View File

@@ -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) {

View File

@@ -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();
} }

View File

@@ -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>);

View File

@@ -228,27 +228,27 @@ namespace ams::erpt::srv {
/* Check if the forced shutdown context exists; if it doesn't, we should create an empty one. */ /* 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) {

View File

@@ -19,5 +19,6 @@
namespace ams::erpt::srv { namespace ams::erpt::srv {
Result SubmitFsInfo(); Result SubmitFsInfo();
void ClearFsInfo();
} }

View File

@@ -363,6 +363,8 @@ namespace ams::erpt::srv {
R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken)); R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken));
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address)); R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address));
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count)); R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count));
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReasonResult, ei.last_deactivate_reason_result));
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReason, ei.last_deactivate_reason));
/* Submit the record. */ /* Submit the record. */
R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record)));
@@ -496,4 +498,27 @@ namespace ams::erpt::srv {
R_SUCCEED(); R_SUCCEED();
} }
void ClearFsInfo() {
Context::ClearContext(CategoryId_NANDTypeInfo);
Context::ClearContext(CategoryId_NANDSpeedModeInfo);
Context::ClearContext(CategoryId_NANDExtendedCsd);
Context::ClearContext(CategoryId_NANDPatrolInfo);
Context::ClearContext(CategoryId_NANDErrorInfo);
Context::ClearContext(CategoryId_NANDDriverLog);
Context::ClearContext(CategoryId_MicroSDTypeInfo);
Context::ClearContext(CategoryId_MicroSDSpeedModeInfo);
Context::ClearContext(CategoryId_SdCardSizeSpec);
Context::ClearContext(CategoryId_SdCardActivationInfo);
Context::ClearContext(CategoryId_SdCardErrorInfo);
Context::ClearContext(CategoryId_SdCardDriverLog);
Context::ClearContext(CategoryId_GameCardCIDInfo);
Context::ClearContext(CategoryId_GameCardErrorInfo);
Context::ClearContext(CategoryId_GameCardDetailedErrorInfo);
Context::ClearContext(CategoryId_GameCardLogInfo);
Context::ClearContext(CategoryId_FsProxyErrorInfo);
Context::ClearContext(CategoryId_FsProxyErrorInfo2);
Context::ClearContext(CategoryId_FsProxyErrorInfo3);
Context::ClearContext(CategoryId_FsMemoryInfo);
}
} }

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