Compare commits

...

84 Commits

Author SHA1 Message Date
Michael Scire
9df13781c2 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "eb667fea5"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "eb667fea5"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
2021-07-06 07:29:10 -07:00
Michael Scire
283736878d docs: add changelog for 0.19.5 2021-07-06 07:28:12 -07:00
Michael Scire
f863164648 ams: basic support for 12.1.0 2021-07-06 07:13:56 -07:00
Michael Scire
3eb76fcd16 exo: update for 12.1.0 2021-07-06 06:55:59 -07:00
Michael Scire
2088c5a34a kern: fix handling of is_aligned parameter in DevicePageTable 2021-07-04 10:45:14 -07:00
Michael Scire
846cde52e0 fs.mitm: ns registers program index map info, not am 2021-06-28 22:43:56 -07:00
Michael Scire
a3dd445b32 fs.mitm: add OpenDataStorageWithProgramIndex support (theoretically, closes #1250) 2021-06-28 22:24:26 -07:00
Michael Scire
c362838e11 erpt: fix 0x100 byte memory leak on creation of new report 2021-06-28 17:36:42 -07:00
Michael Scire
e086022b77 build: use DWARFv4 explicitly for IDA compatibility with debug elfs 2021-06-25 23:48:41 -07:00
Michael Scire
70c1bad08b git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "cbc294c3"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "cbc294c3"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-22 16:13:04 -07:00
Michael Scire
38f9a76ba0 emummc: add custom ld/specs file 2021-06-22 16:12:27 -07:00
Michael Scire
4892ffae15 kern: implement improved [new page tables are zero] invariant 2021-06-17 13:03:46 -07:00
Michael Scire
25305257d6 kern: fix missing peak set in KResourceLimit::SetLimitValue 2021-06-17 12:57:56 -07:00
Michael Scire
e423aef033 kern: ensure InitArguments do not cross page boundaries 2021-06-17 12:49:25 -07:00
Michael Scire
8a6afe7909 dns.mitm: fix wildcardcmp failure case (#1539) 2021-06-15 16:35:26 -07:00
Aurora
c02f32f1bf reboot_to_payload: Use ams:bpc API to set payload, reboot safely and prevent usage on Mariko (#1543) 2021-06-13 16:55:46 -05:00
Michael Scire
2ab01ad33c git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "11ea38a7"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "11ea38a7"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-08 08:09:48 -07:00
Michael Scire
3dbc79dd5c ams: bump version to 0.19.4 2021-06-08 08:09:05 -07:00
Michael Scire
90b54c03b3 git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "219c723c"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "219c723c"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-08 07:50:35 -07:00
Michael Scire
7821241356 kern: fix enormous whoops 2021-05-31 04:20:59 -07:00
Michael Scire
8fea8d9b2e sm: lighten abort restrictions on mitm handle acquisition (closes #1528) 2021-05-30 22:53:32 -07:00
Michael Scire
dcdf46f576 kern: slightly improve genericity of debugger break event 2021-05-30 21:13:42 -07:00
Michael Scire
df5537b748 mem: actually fully fix the heap bug, add comments for future self 2021-05-26 23:21:08 -07:00
Michael Scire
0f2855ada8 mem: fix rare crash/logic error in heap allocation code 2021-05-26 20:43:03 -07:00
Michael Scire
c790d03693 libstrat: fix override operator new to be noexcept (closes #1494) 2021-05-16 23:10:13 -07:00
Michael Scire
25be7c5b1b git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "b5b55f60"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "b5b55f60"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-12 22:47:42 -07:00
Michael Scire
7e05e12b83 sf/tipc: treat min/max as true min/max, rather than numeric 2021-05-12 22:43:39 -07:00
Michael Scire
99d7f72c51 warmboot: remove superfluous firmware version check 2021-05-12 16:57:10 -07:00
Michael Scire
691a453d77 docs: amend changelog 2021-05-12 09:11:19 -07:00
Michael Scire
88246f475c git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "9ac6f527"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "9ac6f527"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-12 09:10:13 -07:00
Michael Scire
269d4496b2 docs: update changelog for 0.19.3 2021-05-12 09:08:55 -07:00
Michael Scire
bb4c7a390b ams: update for 12.0.2 2021-05-12 09:08:47 -07:00
Dark-Mind
b846628362 Update issue template to ask whether sysmmc or emummc. 2021-05-12 08:27:21 -07:00
Michael Scire
26fb201518 dns.mitm: handle nullptr hostname 2021-05-10 13:27:14 -07:00
Michael Scire
01ce7cef14 exo: revert section sorting 2021-05-10 07:59:38 -07:00
Michael Scire
3f3aaa01fa git subrepo clone --force https://github.com/m4xw/emummc
subrepo:
  subdir:   "emummc"
  merged:   "c6717b93"
upstream:
  origin:   "https://github.com/m4xw/emummc"
  branch:   "develop"
  commit:   "c6717b93"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-10 07:50:39 -07:00
Michael Scire
bf8de39e69 ams: move around abort handler to avoid linker errors 2021-05-07 17:49:10 -07:00
Michael Scire
6bb4253df5 emummc: style-change 2021-05-05 09:34:29 -07:00
Michael Scire
cfd7121574 emummc: advance buffer for multi-file case 2021-05-05 08:44:53 -07:00
Michael Scire
972681c57e emummc: fix file-based accesses that cross file boundaries 2021-05-05 08:37:02 -07:00
Michael Scire
0a11cbc2d6 exo: sort sections by alignment 2021-05-02 10:50:18 -07:00
Michael Scire
32f487abfb sm: update to excise unnecessary library code 2021-05-02 10:33:15 -07:00
Michael Scire
7d61cab01c fs: add access log strings for DirectoryEntryType 2021-04-30 19:19:22 -07:00
Michael Scire
14ed4e4057 erpt: fix reading files that don't exist 2021-04-30 14:44:53 -07:00
Michael Scire
e8ba632606 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "acee57e8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "acee57e8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-30 10:04:30 -07:00
Michael Scire
dbcb1e1564 loader: avoid UB when doing count trailing zeros 2021-04-30 10:03:54 -07:00
Michael Scire
15381409dc fs: fix missed operation rename 2021-04-30 09:02:58 -07:00
Michael Scire
10ad6934ac git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "1c5df037"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "1c5df037"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-30 08:56:36 -07:00
Michael Scire
03e66efd85 docs: add changelog for 0.19.2 2021-04-30 08:56:03 -07:00
Michael Scire
7040e8976d i2c: add aula pmic device code 2021-04-30 08:42:25 -07:00
Michael Scire
296a6af058 boot: update all autogenerated parameters other than charge 2021-04-30 08:37:51 -07:00
Michael Scire
2c332d1cf8 ams: bump api version to 0.19.2 2021-04-30 05:00:25 -07:00
Michael Scire
243d7dc777 ams: write-protect stratosphere.romfs 2021-04-30 04:57:46 -07:00
Michael Scire
355010ad84 erpt: implement forced shutdown detection 2021-04-30 04:21:03 -07:00
Michael Scire
ef0c15b764 erpt: Implement 12.0.0 AppletTotalActiveTime tracking 2021-04-29 21:48:47 -07:00
Michael Scire
0dc308d92a fs: properly implement OperateRangeWithBuffer, correct OperationId names. 2021-04-29 20:09:45 -07:00
Michael Scire
eb5542963f git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "4a48e0ee"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "4a48e0ee"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-29 03:05:29 -07:00
Michael Scire
18673d96cb daybreak: fix compat with newer deko3d 2021-04-29 01:21:09 -07:00
Michael Scire
36f6bdc3a0 fusee/sept: update to suppress spurious gcc warnings 2021-04-29 01:13:48 -07:00
Michael Scire
d6fff49845 exo: remove duplicate flags 2021-04-29 01:07:01 -07:00
Michael Scire
d05e8fb23a exo: fix for newer binutils 2021-04-29 01:04:26 -07:00
Michael Scire
0767d9f8da ams: assume gcc 11 2021-04-28 15:13:29 -07:00
Michael Scire
21f3d29df7 strat: compat with gcc 11 2021-04-26 20:06:28 -07:00
Michael Scire
4f16106702 exo/meso: update for gcc 11 compatibility 2021-04-26 20:06:18 -07:00
Michael Scire
19be54ff95 kern: fix initial process binary load on 2.0.0-4.1.0 (closes #1460) 2021-04-21 19:24:41 -07:00
Michael Scire
ed80d6ec8c util: add compile-time validation tests for intrusive red black trees 2021-04-21 05:06:11 -07:00
Michael Scire
57b6c71c1c util: implement red black trees as templates over macros 2021-04-20 16:56:33 -07:00
Michael Scire
0a11d341b7 kern: fix constant evaluation correctness, codegen tweak 2021-04-20 14:25:06 -07:00
Michael Scire
8010290472 kern: tweak KHandleTable codegen 2021-04-19 18:04:02 -07:00
Michael Scire
fbc526d163 kern: tweak KAutoObject::Open/Close codegen 2021-04-19 18:03:27 -07:00
Michael Scire
5bb790e4a7 erpt: implement AppletActiveTimeInfoList 2021-04-16 00:55:22 -07:00
Michael Scire
0a6219e6e0 kern: add names/links to kern_assembly_offsets.h 2021-04-15 15:43:29 -07:00
Michael Scire
037b04ac60 kern: mostly kill magic numbers in assembly, fix SVCs >= 0x80 2021-04-14 18:01:08 -07:00
Michael Scire
9e563d590b pm: account for 12.0.0 resource limit changes 2021-04-14 00:41:31 -07:00
Michael Scire
bdcf02a3ef tipc: ports use objects in the object manager 2021-04-14 00:34:46 -07:00
Michael Scire
88ac85c423 sm: save 0x1000 in data costs by not aligning server manager to 0x1000 2021-04-14 00:12:21 -07:00
Michael Scire
2e1a93f1d1 strat: no longer materially constrained by sm session limit 2021-04-13 23:58:10 -07:00
Michael Scire
997e4dd665 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "86c2eec8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "86c2eec8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-12 17:14:38 -07:00
Michael Scire
aa2d03d8e1 ams: bump to 0.19.1 2021-04-12 17:14:07 -07:00
Michael Scire
274c1deae4 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "68ddbc73"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "68ddbc73"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-12 17:13:43 -07:00
Michael Scire
d5bbf32a26 docs: add 0.19.1 changelog 2021-04-12 17:13:12 -07:00
Michael Scire
97a251b4b2 ncm: fix iteration of nested-subdirectory content files 2021-04-12 17:10:27 -07:00
Michael Scire
9d30917f4e boot2: migration also not launched in 12.0.0 2021-04-11 10:37:04 -07:00
Michael Scire
c67c29ebd5 ncm: fix random error when deleting content 2021-04-11 05:44:13 -07:00
261 changed files with 4809 additions and 2809 deletions

View File

@@ -49,6 +49,8 @@ X.X.X</br>
- [ Ex: Kosmos' distribution of Atmosphère ]
- Do you have additional kips or sysmodules you're loading:
- Homebrew software installed: [ * ]
- EmuMMC or SysNAND:
- [ If using an EmuMMC, include whether it's partition-based or file-based. ]
### Additional context?

View File

@@ -43,6 +43,7 @@ libraries:
clean:
$(MAKE) -C fusee clean
$(MAKE) -C emummc clean
rm -rf out
dist-no-debug: all

View File

@@ -1,4 +1,46 @@
# Changelog
## 0.19.5
+ Support was added for 12.1.0.
+ LayeredFS support was added for OpenDataStorageWithProgramIndex commands.
+ Certain games using newer (7.0.0+ APIs) which include multiple programs under a single title previously could not be modified.
+ These are now supported as normal, and LayeredFS should have 100% compatibility again.
+ A number of minor issues were fixed, including:
+ The Reboot to Payload NRO was updated to allow the OS to save state prior to rebooting (thanks @AuroraWright)!
+ An issue was fixed that could cause dns.mitm to fail when games requested resolution of an empty string.
+ An issue was fixed that caused a memory leak in the erpt system module.
+ This would eventually cause a system crash after ~540 reports were generated without rebooting.
+ A number of minor improvements were made to improve mesosphere's accuracy.
+ General system stability improvements to enhance the user's experience.
## 0.19.4
+ Support was added for 12.0.3.
+ A number of minor issues were fixed, including:
+ An issue was fixed that could cause heap memory corruption when allocation was highly contended.
+ An issue was fixed that could cause sleep to fail under certain conditions.
+ An issue was fixed that could cause a scheduler slow path to be taken more often than necessary.
+ General system stability improvements to enhance the user's experience.
## 0.19.3
+ Support was added for 12.0.2.
+ A number of minor issues were fixed, including:
+ An issue was fixed in dns.mitm that caused a crash when games attempted to resolve the IP address of nullptr.
+ An issue was fixed in erpt that would cause an abort when booting without having ever booted stock previously.
+ An issue was fixed in (file-based) emummc that caused an error on system format/downloading certain games.
+ General system stability improvements to enhance the user's experience.
## 0.19.2
+ Atmosphère's components were further updated to reflect latest official behaviors as of 12.0.0.
+ Notably, `erpt` was updated to implement the new forced shutdown detection feature.
+ When a forced-shutdown occurs, an erpt_report will be generated and saved to the SD card on the next boot.
+ Atmosphere-libs was updated to use GCC 11 (latest devkitA64/devkitARM releases).
+ Initial inspections show mild-to-moderate optimizer improvements in several important places (kernel is 0x3000 smaller).
+ General system stability improvements to enhance the user's experience.
+ A number of minor issues were fixed, including:
+ A bug was fixed that caused a black screen when attempting to boot firmware versions 2.0.0-4.1.0.
+ A bug was fixed that caused sm to abort when at the session limit, rather than returning error codes.
+ A bug was fixed that allowed for resource exhaustion on 12.0.0, under certain circumstances.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.1
+ An issue was fixed that caused a fatal error when using official `migration` services to transfer data between consoles.
+ An issue was fixed in `ncm` that caused an error when the OS tried to enumerate installed SD card content.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.0
+ Support was added for 12.0.0.
+ `mesosphère` was updated to reflect the latest official kernel behavior.

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emuMMC
branch = develop
commit = b355ee6a8f376faa615785419c7d73a8814d9d65
parent = b24784f5c13a142bd0cb5d7edb82691c71f4bd00
commit = cbc294c390ed73bb281bc1028a8899c053427112
parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
method = rebase
cmdver = 0.4.1

View File

@@ -32,7 +32,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LDFLAGS = -specs=$(EMUMMCDIR)/emummc.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ifneq ($(BUILD),$(notdir $(CURDIR)))

201
emummc/emummc.ld Normal file
View File

@@ -0,0 +1,201 @@
OUTPUT_ARCH(aarch64)
ENTRY(_start)
PHDRS
{
code PT_LOAD FLAGS(5) /* Read | Execute */;
rodata PT_LOAD FLAGS(4) /* Read */;
data PT_LOAD FLAGS(6) /* Read | Write */;
dyn PT_DYNAMIC;
}
SECTIONS
{
/* =========== CODE section =========== */
PROVIDE(__start__ = 0x0);
. = __start__;
__code_start = . ;
.crt0 :
{
KEEP (*(.crt0))
. = ALIGN(8);
} :code
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
} :code
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
} :code
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(8);
} :code
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
} :code
/* =========== RODATA section =========== */
. = ALIGN(0x1000);
__rodata_start = . ;
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
} :rodata
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
.dynamic : { *(.dynamic) } :rodata :dyn
.dynsym : { *(.dynsym) } :rodata
.dynstr : { *(.dynstr) } :rodata
.rela.dyn : { *(.rela.*) } :rodata
.interp : { *(.interp) } :rodata
.hash : { *(.hash) } :rodata
.gnu.hash : { *(.gnu.hash) } :rodata
.gnu.version : { *(.gnu.version) } :rodata
.gnu.version_d : { *(.gnu.version_d) } :rodata
.gnu.version_r : { *(.gnu.version_r) } :rodata
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
/* =========== DATA section =========== */
. = ALIGN(0x1000);
__data_start = . ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
.tdata ALIGN(8) :
{
__tdata_lma = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(8);
__tdata_lma_end = .;
} :data
.tbss ALIGN(8) :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
. = ALIGN(8);
} :data
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} :data
.init_array ALIGN(8) :
{
PROVIDE (__init_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) )
KEEP( *(.init_array .ctors) )
PROVIDE (__init_array_end = .);
} :data
.fini_array ALIGN(8) :
{
PROVIDE (__fini_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) )
KEEP( *(.fini_array .dtors) )
PROVIDE (__fini_array_end = .);
} :data
__got_start__ = .;
.got : { *(.got) *(.igot) } :data
.got.plt : { *(.got.plt) *(.igot.plt) } :data
__got_end__ = .;
.data ALIGN(8) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} :data
__bss_start__ = .;
.bss ALIGN(8) :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
/* Reserve space for the TLS segment of the main thread */
__tls_start = .;
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
__tls_end = .;
} : data
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
. = ALIGN(0x1000);
__argdata__ = ABSOLUTE(.) ;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

8
emummc/emummc.specs Normal file
View File

@@ -0,0 +1,8 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /emummc.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -53,6 +53,8 @@
#include "offsets/1100_exfat.h"
#include "offsets/1200.h"
#include "offsets/1200_exfat.h"
#include "offsets/1203.h"
#include "offsets/1203_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -117,6 +119,8 @@ DEFINE_OFFSET_STRUCT(_1100);
DEFINE_OFFSET_STRUCT(_1100_EXFAT);
DEFINE_OFFSET_STRUCT(_1200);
DEFINE_OFFSET_STRUCT(_1200_EXFAT);
DEFINE_OFFSET_STRUCT(_1203);
DEFINE_OFFSET_STRUCT(_1203_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@@ -194,6 +198,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1200));
case FS_VER_12_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT));
case FS_VER_12_0_3:
return &(GET_OFFSET_STRUCT_NAME(_1203));
case FS_VER_12_0_3_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1203_EXFAT));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@@ -77,6 +77,9 @@ enum FS_VER
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX,
};

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* 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_1203_H__
#define __FS_1203_H__
// Accessor vtable getters
#define FS_OFFSET_1203_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_RTLD 0x688
#define FS_OFFSET_1203_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1203_NAND_MUTEX 0xE38768
#define FS_OFFSET_1203_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1203_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1203_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_H__

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* 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_1203_EXFAT_H__
#define __FS_1203_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_EXFAT_RTLD 0x688
#define FS_OFFSET_1203_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1203_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1203_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1203_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1203_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_EXFAT_H__

View File

@@ -292,6 +292,36 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
{
fp = &f_emu.fp_gpp[sector / f_emu.part_size];
sector = sector % f_emu.part_size;
// Special handling for reads/writes which cross file-boundaries.
if (__builtin_expect(sector + num_sectors > f_emu.part_size, 0))
{
unsigned int remaining = num_sectors;
while (remaining > 0) {
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
return 0; // Out of bounds.
if (is_write)
{
if (f_write_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
else
{
if (f_read_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
buf = (char *)buf + ((u64)cur_sectors << 9);
remaining -= cur_sectors;
sector = 0;
++fp;
}
return 1;
}
}
else
{
@@ -306,14 +336,14 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
break;
}
if (f_lseek(fp, sector << 9) != FR_OK)
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
return 0; // Out of bounds.
uint64_t res = 0;
if (!is_write)
res = !f_read_fast(fp, buf, num_sectors << 9);
res = !f_read_fast(fp, buf, (u64)num_sectors << 9);
else
res = !f_write_fast(fp, buf, num_sectors << 9);
res = !f_write_fast(fp, buf, (u64)num_sectors << 9);
return res;
}

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /mariko_fatal.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /mariko_fatal.ld) --gc-sections --nmagic

View File

@@ -1,4 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic -nostdlib -nostartfiles
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /rebootstub.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /rebootstub.ld) --gc-sections --nmagic

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /sc7fw.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /sc7fw.ld) --gc-sections --nmagic

View File

@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
/* TODO: Update on next change of keys. */
/* Mariko Development Master Kek Source. */
.byte 0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE
.byte 0x75, 0x2D, 0x2E, 0xF3, 0x2F, 0x3F, 0xFE, 0x65, 0xF4, 0xA9, 0x83, 0xB4, 0xED, 0x42, 0x63, 0xBA
/* Mariko Production Master Kek Source. */
.byte 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82
.byte 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1
/* 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. */
@@ -102,6 +102,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04 /* Master key 07 encrypted with Master key 08. */
.byte 0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE /* Master key 08 encrypted with Master key 09. */
.byte 0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4 /* Master key 09 encrypted with Master key 0A. */
.byte 0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C /* Master key 0A encrypted with Master key 0B. */
/* 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. */
@@ -115,33 +116,37 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 /* Master key 07 encrypted with Master key 08. */
.byte 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 /* Master key 08 encrypted with Master key 09. */
.byte 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A /* Master key 09 encrypted with Master key 0A. */
.byte 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 /* Master key 0A encrypted with Master key 0B. */
/* 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 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */
.byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */
.byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */
.byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */
.byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */
.byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */
.byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.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. */
.byte 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */
.byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */
.byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */
.byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */
.byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */
.byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */
.byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.0 Device Master Key Source Source. */
.byte 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 /* 12.1.0 Device Master Key Source Source. */
/* Development Device Master Kek Sources. */
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
.byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */
.byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */
.byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */
.byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */
.byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */
.byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */
.byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.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. */
.byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */
.byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */
.byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */
.byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */
.byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */
.byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */
.byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.0 Device Master Kek Source. */
.byte 0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB /* 12.1.0 Device Master Kek Source. */
/* Production Device Master Kek Sources. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
.byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */
.byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */
.byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */
.byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */
.byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */
.byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */
.byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.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. */
.byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */
.byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */
.byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */
.byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */
.byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */
.byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */
.byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.0 Device Master Kek Source. */
.byte 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 /* 12.1.0 Device Master Kek Source. */

View File

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

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic

View File

@@ -36,7 +36,6 @@ namespace ams::warmboot {
void Main(const Metadata *metadata) {
/* Ensure that we're running under vaguely sane conditions. */
AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic);
AMS_ABORT_UNLESS(metadata->target_firmware <= ams::TargetFirmware_Max);
/* Restrict the bpmp's access to dram. */
if (metadata->target_firmware >= TargetFirmware_4_0_0) {

View File

@@ -1,7 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /warmboot.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s
%(old_link) -T %:getenv(TOPDIR /warmboot.ld) --gc-sections --nmagic

View File

@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_MTC_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -46,6 +47,9 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -53,8 +57,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -46,6 +46,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -53,6 +54,9 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -60,8 +64,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -46,6 +47,9 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -53,8 +57,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -48,6 +48,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE2_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -55,6 +56,9 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -62,8 +66,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) $(INCLUDE) $(DEFINES)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g -gdwarf-4 $(ARCH) $(INCLUDE) $(DEFINES)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -94,6 +94,9 @@ typedef enum {
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX,
} emummc_fs_ver_t;

View File

@@ -348,6 +348,7 @@ uint32_t fuse_get_regulator(void) {
static const uint32_t fuse_version_increment_firmwares[] = {
ATMOSPHERE_TARGET_FIRMWARE_12_0_2,
ATMOSPHERE_TARGET_FIRMWARE_11_0_0,
ATMOSPHERE_TARGET_FIRMWARE_10_0_0,
ATMOSPHERE_TARGET_FIRMWARE_9_1_0,

View File

@@ -429,6 +429,9 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xDC\x2A\x08\x49\x96\xBB\x3C\x01", /* FS_VER_12_0_0 */
"\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", /* FS_VER_12_0_0_EXFAT */
"\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", /* FS_VER_12_0_3 */
"\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", /* FS_VER_12_0_3_EXFAT */
};
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -62,7 +62,7 @@ static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MAST
};
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82, /* Mariko MasterKek seed 0A. */
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
};
static nx_dec_keyblob_t AL16 g_dec_keyblobs[32];
@@ -153,7 +153,7 @@ int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keybl
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
/* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */
desired_keyblob = MASTERKEY_REVISION_910_CURRENT;
desired_keyblob = MASTERKEY_REVISION_C10_CURRENT;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
desired_keyblob = MASTERKEY_REVISION_700_800;
} else {

View File

@@ -44,6 +44,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] = {
{0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04}, /* Master key 07 encrypted with Master key 08. */
{0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE}, /* Master key 08 encrypted with Master key 09. */
{0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4}, /* Master key 09 encrypted with Master key 0A. */
{0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C}, /* Master key 0A encrypted with Master key 0B. */
};
/* Retail unit keys. */
@@ -59,17 +60,19 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] = {
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
{0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A}, /* Master key 09 encrypted with Master key 0A. */
{0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98}, /* Master key 0A encrypted with Master key 0B. */
};
static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
{0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6}, /* 12.1.0 New Device Key Source. */
};
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -80,7 +83,8 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
{0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */
{0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */
{0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
{0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source. */
{0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3}, /* 12.1.0 New Device Keygen Source. */
};
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -91,7 +95,8 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
{0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */
{0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */
{0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
{0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source. */
{0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB}, /* 12.1.0 New Device Keygen Source. */
};
/* Determine the current SoC for Mariko specific code. */

View File

@@ -19,8 +19,8 @@
/* This is glue code to enable master key support across versions. */
/* TODO: Update to 0xC on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xB
/* TODO: Update to 0xD on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xC
#define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01
@@ -32,7 +32,8 @@
#define MASTERKEY_REVISION_700_800 0x07
#define MASTERKEY_REVISION_810 0x08
#define MASTERKEY_REVISION_900 0x09
#define MASTERKEY_REVISION_910_CURRENT 0x0A
#define MASTERKEY_REVISION_910_1203 0x0A
#define MASTERKEY_REVISION_C10_CURRENT 0x0B
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)

View File

@@ -285,7 +285,13 @@ static bool is_nca_present(const char *nca_name) {
static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_1_0) {
CHECK_NCA("9d9d83d68d9517f245f3e8cd7f93c416", 12_1_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2) {
CHECK_NCA("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1);
CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
@@ -392,6 +398,10 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return ATMOSPHERE_TARGET_FIRMWARE_11_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210129", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210422", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_2;
} else if (memcmp(package1loader_header->build_timestamp, "20210607", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_1_0;
} else {
fatal_error("[NXBOOT] Unable to identify package1!\n");
}
@@ -603,6 +613,11 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
/* NOTE: 12.0.0 added a new lotus firmware, but did not burn a fuse. */
/* This is literally undetectable using normal fuses.... */
/* C'est la vie. */
/* Check if the fuses are < 12.0.0, but firmware is >= 12.0.0 */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2 && !(fuse_get_reserved_odm(7) & ~0x00003FFF)) {
kip_patches_set_enable_nogc();
}
}
}

View File

@@ -250,7 +250,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1100_CURRENT) {
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1202_CURRENT) {
return true;
}

View File

@@ -41,7 +41,8 @@
#define PACKAGE2_MAXVER_900 0xC
#define PACKAGE2_MAXVER_910_920 0xD
#define PACKAGE2_MAXVER_1000 0xE
#define PACKAGE2_MAXVER_1100_CURRENT 0xF
#define PACKAGE2_MAXVER_1100 0xF
#define PACKAGE2_MAXVER_1202_CURRENT 0x10
#define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4
@@ -56,7 +57,8 @@
#define PACKAGE2_MINVER_900 0xD
#define PACKAGE2_MINVER_910_920 0xE
#define PACKAGE2_MINVER_1000 0xF
#define PACKAGE2_MINVER_1100_CURRENT 0x10
#define PACKAGE2_MINVER_1100 0x10
#define PACKAGE2_MINVER_1202_CURRENT 0x11
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 44279dbac4cce6413faf5b44bd790b23aa323083
parent = 0f6f13a1ac0b74bcb15850a917023562e71e9c3f
commit = eb667fea5142fd35caf539289603748dd6f4f87e
parent = 283736878ddf2cf1cad731b4bf21f916c7e87054
method = merge
cmdver = 0.4.1
cmdver = 0.4.0

View File

@@ -18,7 +18,7 @@ endif
ATMOSPHERE_BUILD_SETTINGS ?=
export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_SETTINGS := -fPIE -g -gdwarf-4 $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation

View File

@@ -8,19 +8,25 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
#---------------------------------------------------------------------------------
ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm64)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
else ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
endif
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \

View File

@@ -12,7 +12,7 @@ export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \

View File

@@ -34,7 +34,8 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_Unwind_Resume \
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
-Wl,--wrap,_ZNSt11logic_errorC2EPKc \
-Wl,--wrap,exit
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)

View File

@@ -16,7 +16,10 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)

View File

@@ -16,7 +16,10 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)

View File

@@ -20,17 +20,18 @@ namespace ams::pkg1 {
enum KeyGeneration : int {
KeyGeneration_1_0_0 = 0x00,
KeyGeneration_3_0_0 = 0x01,
KeyGeneration_3_0_1 = 0x02,
KeyGeneration_4_0_0 = 0x03,
KeyGeneration_5_0_0 = 0x04,
KeyGeneration_6_0_0 = 0x05,
KeyGeneration_6_2_0 = 0x06,
KeyGeneration_7_0_0 = 0x07,
KeyGeneration_8_1_0 = 0x08,
KeyGeneration_9_0_0 = 0x09,
KeyGeneration_9_1_0 = 0x0A,
KeyGeneration_1_0_0 = 0x00,
KeyGeneration_3_0_0 = 0x01,
KeyGeneration_3_0_1 = 0x02,
KeyGeneration_4_0_0 = 0x03,
KeyGeneration_5_0_0 = 0x04,
KeyGeneration_6_0_0 = 0x05,
KeyGeneration_6_2_0 = 0x06,
KeyGeneration_7_0_0 = 0x07,
KeyGeneration_8_1_0 = 0x08,
KeyGeneration_9_0_0 = 0x09,
KeyGeneration_9_1_0 = 0x0A,
KeyGeneration_12_1_0 = 0x0B,
KeyGeneration_Count,

View File

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

View File

@@ -165,6 +165,7 @@ namespace ams::fuse {
}
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_12_0_2,
TargetFirmware_11_0_0,
TargetFirmware_10_0_0,
TargetFirmware_9_1_0,

View File

@@ -140,6 +140,8 @@ $(OFILES_SRC) : $(HFILES_BIN)
kern_libc_generic.o: CFLAGS += -fno-builtin
kern_k_auto_object.o: CXXFLAGS += -fno-lto
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------

View File

@@ -14,10 +14,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mesosphere/kern_select_assembly_offsets.h>
namespace ams::kern::init {
struct KInitArguments {
struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments {
u64 ttbr0;
u64 ttbr1;
u64 tcr;
@@ -31,5 +32,20 @@ namespace ams::kern::init {
u64 setup_function;
u64 exception_stack;
};
static_assert(alignof(KInitArguments) == util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE));
static_assert(sizeof(KInitArguments) == std::max(INIT_ARGUMENTS_SIZE, util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)));
static_assert(__builtin_offsetof(KInitArguments, ttbr0) == INIT_ARGUMENTS_TTBR0);
static_assert(__builtin_offsetof(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1);
static_assert(__builtin_offsetof(KInitArguments, tcr) == INIT_ARGUMENTS_TCR);
static_assert(__builtin_offsetof(KInitArguments, mair) == INIT_ARGUMENTS_MAIR);
static_assert(__builtin_offsetof(KInitArguments, cpuactlr) == INIT_ARGUMENTS_CPUACTLR);
static_assert(__builtin_offsetof(KInitArguments, cpuectlr) == INIT_ARGUMENTS_CPUECTLR);
static_assert(__builtin_offsetof(KInitArguments, sctlr) == INIT_ARGUMENTS_SCTLR);
static_assert(__builtin_offsetof(KInitArguments, sp) == INIT_ARGUMENTS_SP);
static_assert(__builtin_offsetof(KInitArguments, entrypoint) == INIT_ARGUMENTS_ENTRYPOINT);
static_assert(__builtin_offsetof(KInitArguments, argument) == INIT_ARGUMENTS_ARGUMENT);
static_assert(__builtin_offsetof(KInitArguments, setup_function) == INIT_ARGUMENTS_SETUP_FUNCTION);
static_assert(__builtin_offsetof(KInitArguments, exception_stack) == INIT_ARGUMENTS_EXCEPTION_STACK);
}

View File

@@ -15,6 +15,10 @@
*/
#pragma once
/* TODO: Different header for this? */
#define AMS_KERN_NUM_SUPERVISOR_CALLS 0xC0
/* ams::kern::KThread::StackParameters, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp */
#define THREAD_STACK_PARAMETERS_SIZE 0x30
#define THREAD_STACK_PARAMETERS_SVC_PERMISSION 0x00
#define THREAD_STACK_PARAMETERS_CONTEXT 0x18
@@ -24,4 +28,130 @@
#define THREAD_STACK_PARAMETERS_CURRENT_SVC_ID 0x2B
#define THREAD_STACK_PARAMETERS_IS_CALLING_SVC 0x2C
#define THREAD_STACK_PARAMETERS_IS_IN_EXCEPTION_HANDLER 0x2D
#define THREAD_STACK_PARAMETERS_IS_PINNED 0x2E
#define THREAD_STACK_PARAMETERS_IS_PINNED 0x2E
/* ams::kern::arch::arm64::KThreadContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp */
#define THREAD_CONTEXT_SIZE 0x290
#define THREAD_CONTEXT_CPU_REGISTERS 0x000
#define THREAD_CONTEXT_X19 0x000
#define THREAD_CONTEXT_X20 0x008
#define THREAD_CONTEXT_X21 0x010
#define THREAD_CONTEXT_X22 0x018
#define THREAD_CONTEXT_X23 0x020
#define THREAD_CONTEXT_X24 0x028
#define THREAD_CONTEXT_X25 0x030
#define THREAD_CONTEXT_X26 0x038
#define THREAD_CONTEXT_X27 0x040
#define THREAD_CONTEXT_X28 0x048
#define THREAD_CONTEXT_X29 0x050
#define THREAD_CONTEXT_LR 0x058
#define THREAD_CONTEXT_SP 0x060
#define THREAD_CONTEXT_CPACR 0x068
#define THREAD_CONTEXT_FPCR 0x070
#define THREAD_CONTEXT_FPSR 0x078
#define THREAD_CONTEXT_FPU_REGISTERS 0x080
#define THREAD_CONTEXT_LOCKED 0x280
#define THREAD_CONTEXT_X19_X20 THREAD_CONTEXT_X19
#define THREAD_CONTEXT_X21_X22 THREAD_CONTEXT_X21
#define THREAD_CONTEXT_X23_X24 THREAD_CONTEXT_X23
#define THREAD_CONTEXT_X25_X26 THREAD_CONTEXT_X25
#define THREAD_CONTEXT_X27_X28 THREAD_CONTEXT_X27
#define THREAD_CONTEXT_X29_X30 THREAD_CONTEXT_X29
#define THREAD_CONTEXT_LR_SP THREAD_CONTEXT_LR
#define THREAD_CONTEXT_SP_CPACR THREAD_CONTEXT_SP
#define THREAD_CONTEXT_FPCR_FPSR THREAD_CONTEXT_FPCR
/* ams::kern::arch::arm64::KExceptionContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_exception_context.hpp */
#define EXCEPTION_CONTEXT_SIZE 0x120
#define EXCEPTION_CONTEXT_X0 0x000
#define EXCEPTION_CONTEXT_X1 0x008
#define EXCEPTION_CONTEXT_X2 0x010
#define EXCEPTION_CONTEXT_X3 0x018
#define EXCEPTION_CONTEXT_X4 0x020
#define EXCEPTION_CONTEXT_X5 0x028
#define EXCEPTION_CONTEXT_X6 0x030
#define EXCEPTION_CONTEXT_X7 0x038
#define EXCEPTION_CONTEXT_X8 0x040
#define EXCEPTION_CONTEXT_X9 0x048
#define EXCEPTION_CONTEXT_X10 0x050
#define EXCEPTION_CONTEXT_X11 0x058
#define EXCEPTION_CONTEXT_X12 0x060
#define EXCEPTION_CONTEXT_X13 0x068
#define EXCEPTION_CONTEXT_X14 0x070
#define EXCEPTION_CONTEXT_X15 0x078
#define EXCEPTION_CONTEXT_X16 0x080
#define EXCEPTION_CONTEXT_X17 0x088
#define EXCEPTION_CONTEXT_X18 0x090
#define EXCEPTION_CONTEXT_X19 0x098
#define EXCEPTION_CONTEXT_X20 0x0A0
#define EXCEPTION_CONTEXT_X21 0x0A8
#define EXCEPTION_CONTEXT_X22 0x0B0
#define EXCEPTION_CONTEXT_X23 0x0B8
#define EXCEPTION_CONTEXT_X24 0x0C0
#define EXCEPTION_CONTEXT_X25 0x0C8
#define EXCEPTION_CONTEXT_X26 0x0D0
#define EXCEPTION_CONTEXT_X27 0x0D8
#define EXCEPTION_CONTEXT_X28 0x0E0
#define EXCEPTION_CONTEXT_X29 0x0E8
#define EXCEPTION_CONTEXT_X30 0x0F0
#define EXCEPTION_CONTEXT_SP 0x0F8
#define EXCEPTION_CONTEXT_PC 0x100
#define EXCEPTION_CONTEXT_PSR 0x108
#define EXCEPTION_CONTEXT_TPIDR 0x110
#define EXCEPTION_CONTEXT_X0_X1 EXCEPTION_CONTEXT_X0
#define EXCEPTION_CONTEXT_X2_X3 EXCEPTION_CONTEXT_X2
#define EXCEPTION_CONTEXT_X4_X5 EXCEPTION_CONTEXT_X4
#define EXCEPTION_CONTEXT_X6_X7 EXCEPTION_CONTEXT_X6
#define EXCEPTION_CONTEXT_X8_X9 EXCEPTION_CONTEXT_X8
#define EXCEPTION_CONTEXT_X10_X11 EXCEPTION_CONTEXT_X10
#define EXCEPTION_CONTEXT_X12_X13 EXCEPTION_CONTEXT_X12
#define EXCEPTION_CONTEXT_X14_X15 EXCEPTION_CONTEXT_X14
#define EXCEPTION_CONTEXT_X16_X17 EXCEPTION_CONTEXT_X16
#define EXCEPTION_CONTEXT_X18_X19 EXCEPTION_CONTEXT_X18
#define EXCEPTION_CONTEXT_X20_X21 EXCEPTION_CONTEXT_X20
#define EXCEPTION_CONTEXT_X22_X23 EXCEPTION_CONTEXT_X22
#define EXCEPTION_CONTEXT_X24_X25 EXCEPTION_CONTEXT_X24
#define EXCEPTION_CONTEXT_X26_X27 EXCEPTION_CONTEXT_X26
#define EXCEPTION_CONTEXT_X28_X29 EXCEPTION_CONTEXT_X28
#define EXCEPTION_CONTEXT_X30_SP EXCEPTION_CONTEXT_X30
#define EXCEPTION_CONTEXT_PC_PSR EXCEPTION_CONTEXT_PC
#define EXCEPTION_CONTEXT_X9_X10 EXCEPTION_CONTEXT_X9
#define EXCEPTION_CONTEXT_X19_X20 EXCEPTION_CONTEXT_X19
#define EXCEPTION_CONTEXT_X21_X22 EXCEPTION_CONTEXT_X21
#define EXCEPTION_CONTEXT_X23_X24 EXCEPTION_CONTEXT_X23
#define EXCEPTION_CONTEXT_X25_X26 EXCEPTION_CONTEXT_X25
#define EXCEPTION_CONTEXT_X27_X28 EXCEPTION_CONTEXT_X27
#define EXCEPTION_CONTEXT_X29_X30 EXCEPTION_CONTEXT_X29
#define EXCEPTION_CONTEXT_SP_PC EXCEPTION_CONTEXT_SP
#define EXCEPTION_CONTEXT_PSR_TPIDR EXCEPTION_CONTEXT_PSR
/* ams::svc::arch::arm64::ThreadLocalRegion, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libvapours/include/vapours/svc/arch/arm64/svc_thread_local_region.hpp */
#define THREAD_LOCAL_REGION_MESSAGE_BUFFER 0x000
#define THREAD_LOCAL_REGION_DISABLE_COUNT 0x100
#define THREAD_LOCAL_REGION_INTERRUPT_FLAG 0x102
#define THREAD_LOCAL_REGION_SIZE 0x200
/* ams::kern::init::KInitArguments, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp */
#define INIT_ARGUMENTS_SIZE 0x60
#define INIT_ARGUMENTS_TTBR0 0x00
#define INIT_ARGUMENTS_TTBR1 0x08
#define INIT_ARGUMENTS_TCR 0x10
#define INIT_ARGUMENTS_MAIR 0x18
#define INIT_ARGUMENTS_CPUACTLR 0x20
#define INIT_ARGUMENTS_CPUECTLR 0x28
#define INIT_ARGUMENTS_SCTLR 0x30
#define INIT_ARGUMENTS_SP 0x38
#define INIT_ARGUMENTS_ENTRYPOINT 0x40
#define INIT_ARGUMENTS_ARGUMENT 0x48
#define INIT_ARGUMENTS_SETUP_FUNCTION 0x50
#define INIT_ARGUMENTS_EXCEPTION_STACK 0x58
/* ams::kern::KScheduler (::SchedulingState), https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp */
/* NOTE: Due to constraints on ldarb relative offsets, KSCHEDULER_NEEDS_SCHEDULING cannot trivially be changed, and will require assembly edits. */
#define KSCHEDULER_NEEDS_SCHEDULING 0x00
#define KSCHEDULER_INTERRUPT_TASK_THREAD_RUNNABLE 0x01
#define KSCHEDULER_HIGHEST_PRIORITY_THREAD 0x10
#define KSCHEDULER_IDLE_THREAD_STACK 0x18

View File

@@ -43,6 +43,42 @@ namespace ams::kern::arch::arm64 {
}
}
};
static_assert(sizeof(KExceptionContext) == 0x120);
static_assert(sizeof(KExceptionContext) == EXCEPTION_CONTEXT_SIZE);
static_assert(__builtin_offsetof(KExceptionContext, x[ 0]) == EXCEPTION_CONTEXT_X0);
static_assert(__builtin_offsetof(KExceptionContext, x[ 1]) == EXCEPTION_CONTEXT_X1);
static_assert(__builtin_offsetof(KExceptionContext, x[ 2]) == EXCEPTION_CONTEXT_X2);
static_assert(__builtin_offsetof(KExceptionContext, x[ 3]) == EXCEPTION_CONTEXT_X3);
static_assert(__builtin_offsetof(KExceptionContext, x[ 4]) == EXCEPTION_CONTEXT_X4);
static_assert(__builtin_offsetof(KExceptionContext, x[ 5]) == EXCEPTION_CONTEXT_X5);
static_assert(__builtin_offsetof(KExceptionContext, x[ 6]) == EXCEPTION_CONTEXT_X6);
static_assert(__builtin_offsetof(KExceptionContext, x[ 7]) == EXCEPTION_CONTEXT_X7);
static_assert(__builtin_offsetof(KExceptionContext, x[ 8]) == EXCEPTION_CONTEXT_X8);
static_assert(__builtin_offsetof(KExceptionContext, x[ 9]) == EXCEPTION_CONTEXT_X9);
static_assert(__builtin_offsetof(KExceptionContext, x[10]) == EXCEPTION_CONTEXT_X10);
static_assert(__builtin_offsetof(KExceptionContext, x[11]) == EXCEPTION_CONTEXT_X11);
static_assert(__builtin_offsetof(KExceptionContext, x[12]) == EXCEPTION_CONTEXT_X12);
static_assert(__builtin_offsetof(KExceptionContext, x[13]) == EXCEPTION_CONTEXT_X13);
static_assert(__builtin_offsetof(KExceptionContext, x[14]) == EXCEPTION_CONTEXT_X14);
static_assert(__builtin_offsetof(KExceptionContext, x[15]) == EXCEPTION_CONTEXT_X15);
static_assert(__builtin_offsetof(KExceptionContext, x[16]) == EXCEPTION_CONTEXT_X16);
static_assert(__builtin_offsetof(KExceptionContext, x[17]) == EXCEPTION_CONTEXT_X17);
static_assert(__builtin_offsetof(KExceptionContext, x[18]) == EXCEPTION_CONTEXT_X18);
static_assert(__builtin_offsetof(KExceptionContext, x[19]) == EXCEPTION_CONTEXT_X19);
static_assert(__builtin_offsetof(KExceptionContext, x[20]) == EXCEPTION_CONTEXT_X20);
static_assert(__builtin_offsetof(KExceptionContext, x[21]) == EXCEPTION_CONTEXT_X21);
static_assert(__builtin_offsetof(KExceptionContext, x[22]) == EXCEPTION_CONTEXT_X22);
static_assert(__builtin_offsetof(KExceptionContext, x[23]) == EXCEPTION_CONTEXT_X23);
static_assert(__builtin_offsetof(KExceptionContext, x[24]) == EXCEPTION_CONTEXT_X24);
static_assert(__builtin_offsetof(KExceptionContext, x[25]) == EXCEPTION_CONTEXT_X25);
static_assert(__builtin_offsetof(KExceptionContext, x[26]) == EXCEPTION_CONTEXT_X26);
static_assert(__builtin_offsetof(KExceptionContext, x[27]) == EXCEPTION_CONTEXT_X27);
static_assert(__builtin_offsetof(KExceptionContext, x[28]) == EXCEPTION_CONTEXT_X28);
static_assert(__builtin_offsetof(KExceptionContext, x[29]) == EXCEPTION_CONTEXT_X29);
static_assert(__builtin_offsetof(KExceptionContext, x[30]) == EXCEPTION_CONTEXT_X30);
static_assert(__builtin_offsetof(KExceptionContext, sp) == EXCEPTION_CONTEXT_SP);
static_assert(__builtin_offsetof(KExceptionContext, pc) == EXCEPTION_CONTEXT_PC);
static_assert(__builtin_offsetof(KExceptionContext, psr) == EXCEPTION_CONTEXT_PSR);
static_assert(__builtin_offsetof(KExceptionContext, tpidr) == EXCEPTION_CONTEXT_TPIDR);
}

View File

@@ -79,8 +79,38 @@ namespace ams::kern::arch::arm64 {
const u128 *GetFpuRegisters() const { return m_fpu_registers; }
public:
static void OnThreadTerminating(const KThread *thread);
public:
static consteval bool ValidateOffsets();
};
consteval bool KThreadContext::ValidateOffsets() {
static_assert(sizeof(KThreadContext) == THREAD_CONTEXT_SIZE);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.registers) == THREAD_CONTEXT_CPU_REGISTERS);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x19) == THREAD_CONTEXT_X19);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x20) == THREAD_CONTEXT_X20);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x21) == THREAD_CONTEXT_X21);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x22) == THREAD_CONTEXT_X22);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x23) == THREAD_CONTEXT_X23);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x24) == THREAD_CONTEXT_X24);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x25) == THREAD_CONTEXT_X25);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x26) == THREAD_CONTEXT_X26);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x27) == THREAD_CONTEXT_X27);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x28) == THREAD_CONTEXT_X28);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x29) == THREAD_CONTEXT_X29);
static_assert(__builtin_offsetof(KThreadContext, m_lr) == THREAD_CONTEXT_LR);
static_assert(__builtin_offsetof(KThreadContext, m_sp) == THREAD_CONTEXT_SP);
static_assert(__builtin_offsetof(KThreadContext, m_cpacr) == THREAD_CONTEXT_CPACR);
static_assert(__builtin_offsetof(KThreadContext, m_fpcr) == THREAD_CONTEXT_FPCR);
static_assert(__builtin_offsetof(KThreadContext, m_fpsr) == THREAD_CONTEXT_FPSR);
static_assert(__builtin_offsetof(KThreadContext, m_fpu_registers) == THREAD_CONTEXT_FPU_REGISTERS);
static_assert(__builtin_offsetof(KThreadContext, m_locked) == THREAD_CONTEXT_LOCKED);
return true;
}
static_assert(KThreadContext::ValidateOffsets());
void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread);
}

View File

@@ -69,7 +69,7 @@ namespace ams::kern::board::nintendo::nx {
Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size);
Result Detach(ams::svc::DeviceName device_name);
Result Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings);
Result Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings);
Result Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address);
void Unmap(KDeviceVirtualAddress device_address, size_t size) {

View File

@@ -24,6 +24,8 @@
namespace ams::kern::init {
static_assert(util::IsPowerOfTwo(alignof(KInitArguments)) && util::IsPowerOfTwo(sizeof(KInitArguments)));
KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
}

View File

@@ -37,4 +37,6 @@ namespace ams::kern {
KVirtualAddress GetInitialProcessBinaryAddress();
size_t GetInitialProcessesSecureMemorySize();
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end);
}

View File

@@ -121,36 +121,8 @@ namespace ams::kern {
}
}
NOINLINE bool Open() {
MESOSPHERE_ASSERT_THIS();
/* Atomically increment the reference count, only if it's positive. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire);
do {
if (AMS_UNLIKELY(cur_ref_count == 0)) {
MESOSPHERE_AUDIT(cur_ref_count != 0);
return false;
}
MESOSPHERE_ABORT_UNLESS(cur_ref_count < cur_ref_count + 1);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count + 1, std::memory_order_relaxed));
return true;
}
NOINLINE void Close() {
MESOSPHERE_ASSERT_THIS();
/* Atomically decrement the reference count, not allowing it to become negative. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire);
do {
MESOSPHERE_ABORT_UNLESS(cur_ref_count > 0);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1, std::memory_order_relaxed));
/* If ref count hits zero, schedule the object for destruction. */
if (cur_ref_count - 1 == 0) {
this->ScheduleDestruction();
}
}
bool Open();
void Close();
private:
/* NOTE: This has to be defined *after* KThread is defined. */
/* Nintendo seems to handle this by defining Open/Close() in a cpp, but we'd like them to remain in headers. */

View File

@@ -64,8 +64,11 @@ namespace ams::kern {
m_page_bitmap.Initialize(management_ptr, m_count);
/* Free the pages to the bitmap. */
std::memset(GetPointer<PageBuffer>(m_address), 0, m_count * sizeof(PageBuffer));
for (size_t i = 0; i < m_count; i++) {
/* Ensure the freed page is all-zero. */
cpu::ClearPageToZero(GetPointer<PageBuffer>(m_address) + i);
/* Set the bit for the free page. */
m_page_bitmap.SetBit(i);
}
@@ -99,6 +102,9 @@ namespace ams::kern {
}
void Free(PageBuffer *pb) {
/* Ensure all pages in the heap are zero. */
cpu::ClearPageToZero(pb);
/* Take the lock. */
KScopedInterruptDisable di;
KScopedSpinLock lk(m_lock);

View File

@@ -22,7 +22,7 @@
namespace ams::kern {
template<typename T>
template<typename T, bool ClearNode = false>
class KDynamicSlabHeap {
NON_COPYABLE(KDynamicSlabHeap);
NON_MOVEABLE(KDynamicSlabHeap);
@@ -97,6 +97,13 @@ namespace ams::kern {
T *Allocate() {
T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate());
/* If we successfully allocated and we should clear the node, do so. */
if constexpr (ClearNode) {
if (AMS_LIKELY(allocated != nullptr)) {
reinterpret_cast<Impl::Node *>(allocated)->next = nullptr;
}
}
/* If we fail to allocate, try to get a new page from our next allocator. */
if (AMS_UNLIKELY(allocated == nullptr)) {
if (m_page_allocator != nullptr) {

View File

@@ -131,11 +131,15 @@ namespace ams::kern {
/* Handle pseudo-handles. */
if constexpr (std::derived_from<KProcess, T>) {
if (handle == ams::svc::PseudoHandle::CurrentProcess) {
return GetCurrentProcessPointer();
auto * const cur_process = GetCurrentProcessPointer();
AMS_ASSUME(cur_process != nullptr);
return cur_process;
}
} else if constexpr (std::derived_from<KThread, T>) {
if (handle == ams::svc::PseudoHandle::CurrentThread) {
return GetCurrentThreadPointer();
auto * const cur_thread = GetCurrentThreadPointer();
AMS_ASSUME(cur_thread != nullptr);
return cur_thread;
}
}
@@ -159,8 +163,11 @@ namespace ams::kern {
ALWAYS_INLINE KScopedAutoObject<KAutoObject> GetObjectForIpc(ams::svc::Handle handle, KThread *cur_thread) const {
/* Handle pseudo-handles. */
AMS_ASSUME(cur_thread != nullptr);
if (handle == ams::svc::PseudoHandle::CurrentProcess) {
return static_cast<KAutoObject *>(static_cast<void *>(cur_thread->GetOwnerProcess()));
auto * const cur_process = static_cast<KAutoObject *>(static_cast<void *>(cur_thread->GetOwnerProcess()));
AMS_ASSUME(cur_process != nullptr);
return cur_process;
}
if (handle == ams::svc::PseudoHandle::CurrentThread) {
return static_cast<KAutoObject *>(cur_thread);
@@ -305,7 +312,7 @@ namespace ams::kern {
return true;
}
constexpr ALWAYS_INLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const {
constexpr NOINLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const {
MESOSPHERE_ASSERT_THIS();
/* Handles must not have reserved bits set. */

View File

@@ -160,7 +160,7 @@ namespace ams::kern {
};
constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) {
return static_cast<KMemoryPermission>((perm & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((perm & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None));
return static_cast<KMemoryPermission>((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None));
}
enum KMemoryAttribute : u8 {

View File

@@ -175,7 +175,14 @@ namespace ams::kern {
return std::make_tuple(total_size, kernel_size);
}
static void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start);
static void InitializeLinearMemoryAddresses(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start) {
/* Set static differences. */
s_linear_phys_to_virt_diff = GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start);
s_linear_virt_to_phys_diff = GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start);
}
static void InitializeLinearMemoryRegionTrees();
static size_t GetResourceRegionSizeForInit();
static NOINLINE auto GetKernelRegionExtents() { return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel); }

View File

@@ -66,11 +66,41 @@ namespace ams::kern {
consteval operator KMemoryRegionType() const { return static_cast<KMemoryRegionType>(m_value); }
consteval ValueType GetValue() const { return m_value; }
consteval const KMemoryRegionTypeValue &Finalize() { m_finalized = true; return *this; }
consteval const KMemoryRegionTypeValue &SetSparseOnly() { m_sparse_only = true; return *this; }
consteval const KMemoryRegionTypeValue &SetDenseOnly() { m_dense_only = true; return *this; }
consteval const KMemoryRegionTypeValue Finalize() {
AMS_ASSUME(!m_finalized);
consteval KMemoryRegionTypeValue &SetAttribute(KMemoryRegionAttr attr) { AMS_ASSUME(!m_finalized); m_value |= attr; return *this; }
KMemoryRegionTypeValue new_type = *this;
new_type.m_finalized = true;
return new_type;
}
consteval const KMemoryRegionTypeValue SetSparseOnly() {
AMS_ASSUME(!m_finalized);
AMS_ASSUME(!m_sparse_only);
AMS_ASSUME(!m_dense_only);
KMemoryRegionTypeValue new_type = *this;
new_type.m_sparse_only = true;
return new_type;
}
consteval const KMemoryRegionTypeValue SetDenseOnly() {
AMS_ASSUME(!m_finalized);
AMS_ASSUME(!m_sparse_only);
AMS_ASSUME(!m_dense_only);
KMemoryRegionTypeValue new_type = *this;
new_type.m_dense_only = true;
return new_type;
}
consteval KMemoryRegionTypeValue SetAttribute(KMemoryRegionAttr attr) {
AMS_ASSUME(!m_finalized);
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= attr;
return new_type;
}
consteval KMemoryRegionTypeValue DeriveInitial(size_t i, size_t next = BITSIZEOF(ValueType)) const {
AMS_ASSUME(!m_finalized);

View File

@@ -107,8 +107,11 @@ namespace ams::kern {
Node *Peek() const { return m_root; }
Node *Pop() {
Node *r = m_root;
m_root = m_root->m_next;
Node * const r = m_root;
m_root = r->m_next;
r->m_next = nullptr;
return r;
}
};

View File

@@ -25,18 +25,20 @@ namespace ams::kern {
class PageTablePage {
private:
u8 m_buffer[PageSize];
public:
ALWAYS_INLINE PageTablePage() { /* Do not initialize anything. */ }
};
static_assert(sizeof(PageTablePage) == PageSize);
}
class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage> {
class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage, true> {
public:
using RefCount = u16;
static constexpr size_t PageTableSize = sizeof(impl::PageTablePage);
static_assert(PageTableSize == PageSize);
private:
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage>;
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage, true>;
private:
RefCount *m_ref_counts;
public:
@@ -72,9 +74,6 @@ namespace ams::kern {
}
void Free(KVirtualAddress addr) {
/* Ensure all pages in the heap are zero. */
cpu::ClearPageToZero(GetVoidPointer(addr));
/* Free the page. */
BaseHeap::Free(GetPointer<impl::PageTablePage>(addr));
}

View File

@@ -194,8 +194,20 @@ namespace ams::kern {
static bool s_scheduler_update_needed;
static KSchedulerPriorityQueue s_priority_queue;
static LockType s_scheduler_lock;
public:
static consteval bool ValidateAssemblyOffsets();
};
consteval bool KScheduler::ValidateAssemblyOffsets() {
static_assert(__builtin_offsetof(KScheduler, m_state.needs_scheduling) == KSCHEDULER_NEEDS_SCHEDULING);
static_assert(__builtin_offsetof(KScheduler, m_state.interrupt_task_thread_runnable) == KSCHEDULER_INTERRUPT_TASK_THREAD_RUNNABLE);
static_assert(__builtin_offsetof(KScheduler, m_state.highest_priority_thread) == KSCHEDULER_HIGHEST_PRIORITY_THREAD);
static_assert(__builtin_offsetof(KScheduler, m_state.idle_thread_stack) == KSCHEDULER_IDLE_THREAD_STACK);
return true;
}
static_assert(KScheduler::ValidateAssemblyOffsets());
class KScopedSchedulerLock : KScopedLock<KScheduler::LockType> {
public:
explicit ALWAYS_INLINE KScopedSchedulerLock() : KScopedLock(KScheduler::s_scheduler_lock) { /* ... */ }

View File

@@ -136,7 +136,7 @@ namespace ams::kern {
static_assert(sizeof(SyncObjectBuffer::m_sync_objects) == sizeof(SyncObjectBuffer::m_handles));
struct ConditionVariableComparator {
struct LightCompareType {
struct RedBlackKeyType {
uintptr_t m_cv_key;
s32 m_priority;
@@ -149,7 +149,7 @@ namespace ams::kern {
}
};
template<typename T> requires (std::same_as<T, KThread> || std::same_as<T, LightCompareType>)
template<typename T> requires (std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>)
static constexpr ALWAYS_INLINE int Compare(const T &lhs, const KThread &rhs) {
const uintptr_t l_key = lhs.GetConditionVariableKey();
const uintptr_t r_key = rhs.GetConditionVariableKey();
@@ -165,8 +165,8 @@ namespace ams::kern {
}
}
};
static_assert(ams::util::HasLightCompareType<ConditionVariableComparator>);
static_assert(std::same_as<ams::util::LightCompareType<ConditionVariableComparator, void>, ConditionVariableComparator::LightCompareType>);
static_assert(ams::util::HasRedBlackKeyType<ConditionVariableComparator>);
static_assert(std::same_as<ams::util::RedBlackKeyType<ConditionVariableComparator, void>, ConditionVariableComparator::RedBlackKeyType>);
private:
static inline std::atomic<u64> s_next_thread_id = 0;
private:
@@ -487,7 +487,7 @@ namespace ams::kern {
constexpr void *GetThreadLocalRegionHeapAddress() const { return m_tls_heap_address; }
constexpr KSynchronizationObject **GetSynchronizationObjectBuffer() { return std::addressof(m_sync_object_buffer.m_sync_objects[0]); }
constexpr ams::svc::Handle *GetHandleBuffer() { return std::addressof(m_sync_object_buffer.m_handles[sizeof(m_sync_object_buffer.m_sync_objects) / sizeof(ams::svc::Handle) - ams::svc::ArgumentHandleCountMax]); }
constexpr ams::svc::Handle *GetHandleBuffer() { return std::addressof(m_sync_object_buffer.m_handles[sizeof(m_sync_object_buffer.m_sync_objects) / (sizeof(ams::svc::Handle)) - ams::svc::ArgumentHandleCountMax]); }
u16 GetUserDisableCount() const { return static_cast<ams::svc::ThreadLocalRegion *>(m_tls_heap_address)->disable_count; }
void SetInterruptFlag() const { static_cast<ams::svc::ThreadLocalRegion *>(m_tls_heap_address)->interrupt_flag = 1; }
@@ -546,7 +546,7 @@ namespace ams::kern {
constexpr u32 GetSuspendFlags() const { return m_suspend_allowed_flags & m_suspend_request_flags; }
constexpr bool IsSuspended() const { return this->GetSuspendFlags() != 0; }
constexpr bool IsSuspendRequested(SuspendType type) const { return (m_suspend_request_flags & (1u << (ThreadState_SuspendShift + type))) != 0; }
constexpr bool IsSuspendRequested(SuspendType type) const { return (m_suspend_request_flags & (1u << (util::ToUnderlying(ThreadState_SuspendShift) + util::ToUnderlying(type)))) != 0; }
constexpr bool IsSuspendRequested() const { return m_suspend_request_flags != 0; }
void RequestSuspend(SuspendType type);
void Resume(SuspendType type);

View File

@@ -105,4 +105,10 @@ namespace ams::kern {
}
};
/* Miscellaneous sanity checking. */
static_assert(ams::svc::ThreadLocalRegionSize == THREAD_LOCAL_REGION_SIZE);
static_assert(__builtin_offsetof(ams::svc::ThreadLocalRegion, message_buffer) == THREAD_LOCAL_REGION_MESSAGE_BUFFER);
static_assert(__builtin_offsetof(ams::svc::ThreadLocalRegion, disable_count) == THREAD_LOCAL_REGION_DISABLE_COUNT);
static_assert(__builtin_offsetof(ams::svc::ThreadLocalRegion, interrupt_flag) == THREAD_LOCAL_REGION_INTERRUPT_FLAG);
}

View File

@@ -20,7 +20,7 @@
namespace ams::kern::svc {
static constexpr size_t NumSupervisorCalls = 0xC0;
static constexpr size_t NumSupervisorCalls = AMS_KERN_NUM_SUPERVISOR_CALLS;
#define AMS_KERN_SVC_DECLARE_ENUM_ID(ID, RETURN_TYPE, NAME, ...) \
SvcId_##NAME = ID,

View File

@@ -279,9 +279,10 @@ namespace ams::kern::arch::arm64 {
if (l1_entry->IsTable()) {
L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, cur_address);
if (l2_entry->IsTable()) {
KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable());
const KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable());
if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) {
while (!this->GetPageTableManager().Close(l3_table, 1)) { /* ... */ }
ClearPageTable(l3_table);
this->GetPageTableManager().Free(l3_table);
}
}
@@ -292,16 +293,21 @@ namespace ams::kern::arch::arm64 {
for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L1BlockSize) {
L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address);
if (l1_entry->IsTable()) {
KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable());
const KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable());
if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) {
while (!this->GetPageTableManager().Close(l2_table, 1)) { /* ... */ }
ClearPageTable(l2_table);
this->GetPageTableManager().Free(l2_table);
}
}
}
/* Free the L1 table. */
this->GetPageTableManager().Free(reinterpret_cast<uintptr_t>(impl.Finalize()));
{
const KVirtualAddress l1_table = reinterpret_cast<uintptr_t>(impl.Finalize());
ClearPageTable(l1_table);
this->GetPageTableManager().Free(l1_table);
}
/* Perform inherited finalization. */
KPageTableBase::Finalize();

View File

@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <mesosphere/kern_build_config.hpp>
#include <mesosphere/kern_select_assembly_offsets.h>
#if defined(MESOSPHERE_ENABLE_PANIC_REGISTER_DUMP)
@@ -32,28 +33,28 @@
\
/* Save x0/x1/sp to the context. */ \
ldr x1, [sp, #(8 * 0)]; \
str x1, [x0, #(8 * 0)]; \
str x1, [x0, #(EXCEPTION_CONTEXT_X0)]; \
ldr x1, [sp, #(8 * 1)]; \
str x1, [x0, #(8 * 1)]; \
str x1, [x0, #(EXCEPTION_CONTEXT_X1)]; \
\
/* Save all other registers to the context. */ \
stp x2, x3, [x0, #(8 * 2)]; \
stp x4, x5, [x0, #(8 * 4)]; \
stp x6, x7, [x0, #(8 * 6)]; \
stp x8, x9, [x0, #(8 * 8)]; \
stp x10, x11, [x0, #(8 * 10)]; \
stp x12, x13, [x0, #(8 * 12)]; \
stp x14, x15, [x0, #(8 * 14)]; \
stp x16, x17, [x0, #(8 * 16)]; \
stp x18, x19, [x0, #(8 * 18)]; \
stp x20, x21, [x0, #(8 * 20)]; \
stp x22, x23, [x0, #(8 * 22)]; \
stp x24, x25, [x0, #(8 * 24)]; \
stp x26, x27, [x0, #(8 * 26)]; \
stp x28, x29, [x0, #(8 * 28)]; \
stp x2, x3, [x0, #(EXCEPTION_CONTEXT_X2_X3)]; \
stp x4, x5, [x0, #(EXCEPTION_CONTEXT_X4_X5)]; \
stp x6, x7, [x0, #(EXCEPTION_CONTEXT_X6_X7)]; \
stp x8, x9, [x0, #(EXCEPTION_CONTEXT_X8_X9)]; \
stp x10, x11, [x0, #(EXCEPTION_CONTEXT_X10_X11)]; \
stp x12, x13, [x0, #(EXCEPTION_CONTEXT_X12_X13)]; \
stp x14, x15, [x0, #(EXCEPTION_CONTEXT_X14_X15)]; \
stp x16, x17, [x0, #(EXCEPTION_CONTEXT_X16_X17)]; \
stp x18, x19, [x0, #(EXCEPTION_CONTEXT_X18_X19)]; \
stp x20, x21, [x0, #(EXCEPTION_CONTEXT_X20_X21)]; \
stp x22, x23, [x0, #(EXCEPTION_CONTEXT_X22_X23)]; \
stp x24, x25, [x0, #(EXCEPTION_CONTEXT_X24_X25)]; \
stp x26, x27, [x0, #(EXCEPTION_CONTEXT_X26_X27)]; \
stp x28, x29, [x0, #(EXCEPTION_CONTEXT_X28_X29)]; \
\
add x1, sp, #16; \
stp x30, x1, [x0, #(8 * 30)]; \
stp x30, x1, [x0, #(EXCEPTION_CONTEXT_X30_SP)]; \
\
/* Restore x0/x1. */ \
ldp x0, x1, [sp], #16;

View File

@@ -21,15 +21,15 @@
.type _ZN3ams4kern3svc25CallReturnFromException64Ev, %function
_ZN3ams4kern3svc25CallReturnFromException64Ev:
/* Save registers the SVC entry handler didn't. */
stp x12, x13, [sp, #(8 * 12)]
stp x14, x15, [sp, #(8 * 14)]
stp x16, x17, [sp, #(8 * 16)]
str x19, [sp, #(8 * 19)]
stp x20, x21, [sp, #(8 * 20)]
stp x22, x23, [sp, #(8 * 22)]
stp x24, x25, [sp, #(8 * 24)]
stp x26, x26, [sp, #(8 * 26)]
stp x28, x29, [sp, #(8 * 28)]
stp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
stp x14, x15, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
stp x16, x17, [sp, #(EXCEPTION_CONTEXT_X16_X17)]
str x19, [sp, #(EXCEPTION_CONTEXT_X19)]
stp x20, x21, [sp, #(EXCEPTION_CONTEXT_X20_X21)]
stp x22, x23, [sp, #(EXCEPTION_CONTEXT_X22_X23)]
stp x24, x25, [sp, #(EXCEPTION_CONTEXT_X24_X25)]
stp x26, x26, [sp, #(EXCEPTION_CONTEXT_X26_X27)]
stp x28, x29, [sp, #(EXCEPTION_CONTEXT_X28_X29)]
/* Call ams::kern::arch::arm64::ReturnFromException(result). */
bl _ZN3ams4kern4arch5arm6419ReturnFromExceptionENS_6ResultE
@@ -63,7 +63,7 @@ _ZN3ams4kern3svc14RestoreContextEm:
0: /* We should handle DPC. */
/* Check the dpc flags. */
ldrb w8, [sp, #(0x120 + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
ldrb w8, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
cbz w8, 1f
/* We have DPC to do! */
@@ -83,32 +83,32 @@ _ZN3ams4kern3svc14RestoreContextEm:
1: /* We're done with DPC, and should return from the svc. */
/* Clear our in-SVC note. */
strb wzr, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb wzr, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
/* Restore registers. */
ldp x30, x8, [sp, #(8 * 30)]
ldp x9, x10, [sp, #(8 * 32)]
ldr x11, [sp, #(8 * 34)]
ldp x30, x8, [sp, #(EXCEPTION_CONTEXT_X30_SP)]
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
msr sp_el0, x8
msr elr_el1, x9
msr spsr_el1, x10
msr tpidr_el0, x11
ldp x0, x1, [sp, #(8 * 0)]
ldp x2, x3, [sp, #(8 * 2)]
ldp x4, x5, [sp, #(8 * 4)]
ldp x6, x7, [sp, #(8 * 6)]
ldp x8, x9, [sp, #(8 * 8)]
ldp x10, x11, [sp, #(8 * 10)]
ldp x12, x13, [sp, #(8 * 12)]
ldp x14, x15, [sp, #(8 * 14)]
ldp x16, x17, [sp, #(8 * 16)]
ldp x18, x19, [sp, #(8 * 18)]
ldp x20, x21, [sp, #(8 * 20)]
ldp x22, x23, [sp, #(8 * 22)]
ldp x24, x25, [sp, #(8 * 24)]
ldp x26, x27, [sp, #(8 * 26)]
ldp x28, x29, [sp, #(8 * 28)]
ldp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
ldp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
ldp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
ldp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
ldp x8, x9, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
ldp x10, x11, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
ldp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
ldp x14, x15, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
ldp x16, x17, [sp, #(EXCEPTION_CONTEXT_X16_X17)]
ldp x18, x19, [sp, #(EXCEPTION_CONTEXT_X18_X19)]
ldp x20, x21, [sp, #(EXCEPTION_CONTEXT_X20_X21)]
ldp x22, x23, [sp, #(EXCEPTION_CONTEXT_X22_X23)]
ldp x24, x25, [sp, #(EXCEPTION_CONTEXT_X24_X25)]
ldp x26, x27, [sp, #(EXCEPTION_CONTEXT_X26_X27)]
ldp x28, x29, [sp, #(EXCEPTION_CONTEXT_X28_X29)]
/* Return. */
add sp, sp, #0x120
add sp, sp, #(EXCEPTION_CONTEXT_SIZE)
eret

View File

@@ -22,45 +22,45 @@
.type _ZN3ams4kern4arch5arm6412SvcHandler64Ev, %function
_ZN3ams4kern4arch5arm6412SvcHandler64Ev:
/* Create a KExceptionContext for the exception. */
sub sp, sp, #0x120
sub sp, sp, #(EXCEPTION_CONTEXT_SIZE)
/* Save registers needed for ReturnFromException */
stp x9, x10, [sp, #(8 * 9)]
str x11, [sp, #(8 * 11)]
str x18, [sp, #(8 * 18)]
stp x9, x10, [sp, #(EXCEPTION_CONTEXT_X9_X10)]
str x11, [sp, #(EXCEPTION_CONTEXT_X11)]
str x18, [sp, #(EXCEPTION_CONTEXT_X18)]
mrs x8, sp_el0
mrs x9, elr_el1
mrs x10, spsr_el1
mrs x11, tpidr_el0
ldr x18, [sp, #(0x120 + THREAD_STACK_PARAMETERS_CUR_THREAD)]
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
/* Save callee-saved registers. */
stp x19, x20, [sp, #(8 * 19)]
stp x21, x22, [sp, #(8 * 21)]
stp x23, x24, [sp, #(8 * 23)]
stp x25, x26, [sp, #(8 * 25)]
stp x27, x28, [sp, #(8 * 27)]
stp x19, x20, [sp, #(EXCEPTION_CONTEXT_X19_X20)]
stp x21, x22, [sp, #(EXCEPTION_CONTEXT_X21_X22)]
stp x23, x24, [sp, #(EXCEPTION_CONTEXT_X23_X24)]
stp x25, x26, [sp, #(EXCEPTION_CONTEXT_X25_X26)]
stp x27, x28, [sp, #(EXCEPTION_CONTEXT_X27_X28)]
/* Save miscellaneous registers. */
stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)]
stp x29, x30, [sp, #(8 * 29)]
stp x8, x9, [sp, #(8 * 31)]
stp x10, x11, [sp, #(8 * 33)]
stp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
stp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
stp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
stp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
stp x29, x30, [sp, #(EXCEPTION_CONTEXT_X29_X30)]
stp x8, x9, [sp, #(EXCEPTION_CONTEXT_SP_PC)]
stp x10, x11, [sp, #(EXCEPTION_CONTEXT_PSR_TPIDR)]
/* Check if the SVC index is out of range. */
mrs x8, esr_el1
and x8, x8, #0xFF
cmp x8, #0x80
cmp x8, #(AMS_KERN_NUM_SUPERVISOR_CALLS)
b.ge 3f
/* Check the specific SVC permission bit for allowal. */
mov x9, sp
add x9, x9, x8, lsr#3
ldrb w9, [x9, #(0x120 + THREAD_STACK_PARAMETERS_SVC_PERMISSION)]
ldrb w9, [x9, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_SVC_PERMISSION)]
and x10, x8, #0x7
lsr x10, x9, x10
tst x10, #1
@@ -68,11 +68,11 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
/* Check if our disable count allows us to call SVCs. */
mrs x10, tpidrro_el0
ldrh w10, [x10, #0x100]
ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)]
cbz w10, 1f
/* It might not, so check the stack params to see if we must not allow the SVC. */
ldrb w10, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_PINNED)]
ldrb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_PINNED)]
cbz w10, 3f
1: /* We can call the SVC. */
@@ -82,8 +82,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
/* Note that we're calling the SVC. */
mov w10, #1
strb w10, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb w8, [sp, #(0x120 + THREAD_STACK_PARAMETERS_CURRENT_SVC_ID)]
strb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb w8, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CURRENT_SVC_ID)]
/* If we should, trace the svc entry. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING)
@@ -110,7 +110,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
2: /* We completed the SVC, and we should handle DPC. */
/* Check the dpc flags. */
ldrb w8, [sp, #(0x120 + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
ldrb w8, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
cbz w8, 4f
/* We have DPC to do! */
@@ -130,57 +130,57 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
3: /* Invalid SVC. */
/* Setup the context to call into HandleException. */
stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)]
stp xzr, xzr, [sp, #(8 * 8)]
stp xzr, xzr, [sp, #(8 * 10)]
stp xzr, xzr, [sp, #(8 * 12)]
stp xzr, xzr, [sp, #(8 * 14)]
stp xzr, xzr, [sp, #(8 * 16)]
str x19, [sp, #(8 * 19)]
stp x20, x21, [sp, #(8 * 20)]
stp x22, x23, [sp, #(8 * 22)]
stp x24, x25, [sp, #(8 * 24)]
stp x26, x27, [sp, #(8 * 26)]
stp x28, x29, [sp, #(8 * 28)]
stp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
stp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
stp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
stp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X16_X17)]
str x19, [sp, #(EXCEPTION_CONTEXT_X19)]
stp x20, x21, [sp, #(EXCEPTION_CONTEXT_X20_X21)]
stp x22, x23, [sp, #(EXCEPTION_CONTEXT_X22_X23)]
stp x24, x25, [sp, #(EXCEPTION_CONTEXT_X24_X25)]
stp x26, x27, [sp, #(EXCEPTION_CONTEXT_X26_X27)]
stp x28, x29, [sp, #(EXCEPTION_CONTEXT_X28_X29)]
/* Call ams::kern::arch::arm64::HandleException(ams::kern::arch::arm64::KExceptionContext *) */
mov x0, sp
bl _ZN3ams4kern4arch5arm6415HandleExceptionEPNS2_17KExceptionContextE
/* Restore registers. */
ldp x30, x8, [sp, #(8 * 30)]
ldp x9, x10, [sp, #(8 * 32)]
ldr x11, [sp, #(8 * 34)]
ldp x30, x8, [sp, #(EXCEPTION_CONTEXT_X30_SP)]
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
msr sp_el0, x8
msr elr_el1, x9
msr spsr_el1, x10
msr tpidr_el0, x11
ldp x0, x1, [sp, #(8 * 0)]
ldp x2, x3, [sp, #(8 * 2)]
ldp x4, x5, [sp, #(8 * 4)]
ldp x6, x7, [sp, #(8 * 6)]
ldp x8, x9, [sp, #(8 * 8)]
ldp x10, x11, [sp, #(8 * 10)]
ldp x12, x13, [sp, #(8 * 12)]
ldp x14, x15, [sp, #(8 * 14)]
ldp x16, x17, [sp, #(8 * 16)]
ldp x18, x19, [sp, #(8 * 18)]
ldp x20, x21, [sp, #(8 * 20)]
ldp x22, x23, [sp, #(8 * 22)]
ldp x24, x25, [sp, #(8 * 24)]
ldp x26, x27, [sp, #(8 * 26)]
ldp x28, x29, [sp, #(8 * 28)]
ldp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
ldp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
ldp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
ldp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
ldp x8, x9, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
ldp x10, x11, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
ldp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
ldp x14, x15, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
ldp x16, x17, [sp, #(EXCEPTION_CONTEXT_X16_X17)]
ldp x18, x19, [sp, #(EXCEPTION_CONTEXT_X18_X19)]
ldp x20, x21, [sp, #(EXCEPTION_CONTEXT_X20_X21)]
ldp x22, x23, [sp, #(EXCEPTION_CONTEXT_X22_X23)]
ldp x24, x25, [sp, #(EXCEPTION_CONTEXT_X24_X25)]
ldp x26, x27, [sp, #(EXCEPTION_CONTEXT_X26_X27)]
ldp x28, x29, [sp, #(EXCEPTION_CONTEXT_X28_X29)]
/* Return. */
add sp, sp, #0x120
add sp, sp, #(EXCEPTION_CONTEXT_SIZE)
eret
4: /* Return from SVC. */
/* Clear our in-SVC note. */
strb wzr, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb wzr, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
/* If we should, trace the svc exit. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING)
@@ -199,10 +199,10 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
#endif
/* Restore registers. */
ldp x30, x8, [sp, #(8 * 30)]
ldp x9, x10, [sp, #(8 * 32)]
ldr x11, [sp, #(8 * 34)]
ldr x18, [sp, #(8 * 18)]
ldp x30, x8, [sp, #(EXCEPTION_CONTEXT_X30_SP)]
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
ldr x18, [sp, #(EXCEPTION_CONTEXT_X18)]
msr sp_el0, x8
msr elr_el1, x9
msr spsr_el1, x10
@@ -221,7 +221,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
mov x17, xzr
/* Return. */
add sp, sp, #0x120
add sp, sp, #(EXCEPTION_CONTEXT_SIZE)
eret
/* ams::kern::arch::arm64::SvcHandler32() */
@@ -240,36 +240,36 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
mov w7, w7
/* Create a KExceptionContext for the exception. */
sub sp, sp, #0x120
sub sp, sp, #(EXCEPTION_CONTEXT_SIZE)
/* Save system registers */
mrs x17, elr_el1
mrs x20, spsr_el1
mrs x19, tpidr_el0
ldr x18, [sp, #(0x120 + THREAD_STACK_PARAMETERS_CUR_THREAD)]
stp x17, x20, [sp, #(8 * 32)]
str x19, [sp, #(8 * 34)]
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
stp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
str x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
/* Save registers. */
stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)]
stp x8, x9, [sp, #(8 * 8)]
stp x10, x11, [sp, #(8 * 10)]
stp x12, x13, [sp, #(8 * 12)]
stp x14, xzr, [sp, #(8 * 14)]
stp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
stp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
stp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
stp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
stp x8, x9, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
stp x10, x11, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
stp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
stp x14, xzr, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
/* Check if the SVC index is out of range. */
mrs x16, esr_el1
and x16, x16, #0xFF
cmp x16, #0x80
cmp x16, #(AMS_KERN_NUM_SUPERVISOR_CALLS)
b.ge 3f
/* Check the specific SVC permission bit for allowal. */
mov x20, sp
add x20, x20, x16, lsr#3
ldrb w20, [x20, #(0x120 + THREAD_STACK_PARAMETERS_SVC_PERMISSION)]
ldrb w20, [x20, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_SVC_PERMISSION)]
and x17, x16, #0x7
lsr x17, x20, x17
tst x17, #1
@@ -277,11 +277,11 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
/* Check if our disable count allows us to call SVCs. */
mrs x15, tpidrro_el0
ldrh w15, [x15, #0x100]
ldrh w15, [x15, #(THREAD_LOCAL_REGION_DISABLE_COUNT)]
cbz w15, 1f
/* It might not, so check the stack params to see if we must not allow the SVC. */
ldrb w15, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_PINNED)]
ldrb w15, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_PINNED)]
cbz w15, 3f
1: /* We can call the SVC. */
@@ -291,8 +291,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
/* Note that we're calling the SVC. */
mov w15, #1
strb w15, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb w16, [sp, #(0x120 + THREAD_STACK_PARAMETERS_CURRENT_SVC_ID)]
strb w15, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb w16, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CURRENT_SVC_ID)]
/* If we should, trace the svc entry. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING)
@@ -319,7 +319,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
2: /* We completed the SVC, and we should handle DPC. */
/* Check the dpc flags. */
ldrb w16, [sp, #(0x120 + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
ldrb w16, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_DPC_FLAGS)]
cbz w16, 4f
/* We have DPC to do! */
@@ -339,45 +339,45 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
3: /* Invalid SVC. */
/* Setup the context to call into HandleException. */
stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)]
stp xzr, xzr, [sp, #(8 * 16)]
stp xzr, xzr, [sp, #(8 * 18)]
stp xzr, xzr, [sp, #(8 * 20)]
stp xzr, xzr, [sp, #(8 * 22)]
stp xzr, xzr, [sp, #(8 * 24)]
stp xzr, xzr, [sp, #(8 * 26)]
stp xzr, xzr, [sp, #(8 * 28)]
stp xzr, xzr, [sp, #(8 * 30)]
stp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
stp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
stp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
stp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X16_X17)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X18_X19)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X20_X21)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X22_X23)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X24_X25)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X26_X27)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X28_X29)]
stp xzr, xzr, [sp, #(EXCEPTION_CONTEXT_X30_SP)]
/* Call ams::kern::arch::arm64::HandleException(ams::kern::arch::arm64::KExceptionContext *) */
mov x0, sp
bl _ZN3ams4kern4arch5arm6415HandleExceptionEPNS2_17KExceptionContextE
/* Restore registers. */
ldp x17, x20, [sp, #(8 * 32)]
ldr x19, [sp, #(8 * 34)]
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
msr elr_el1, x17
msr spsr_el1, x20
msr tpidr_el0, x19
ldp x0, x1, [sp, #(8 * 0)]
ldp x2, x3, [sp, #(8 * 2)]
ldp x4, x5, [sp, #(8 * 4)]
ldp x6, x7, [sp, #(8 * 6)]
ldp x8, x9, [sp, #(8 * 8)]
ldp x10, x11, [sp, #(8 * 10)]
ldp x12, x13, [sp, #(8 * 12)]
ldp x14, x15, [sp, #(8 * 14)]
ldp x0, x1, [sp, #(EXCEPTION_CONTEXT_X0_X1)]
ldp x2, x3, [sp, #(EXCEPTION_CONTEXT_X2_X3)]
ldp x4, x5, [sp, #(EXCEPTION_CONTEXT_X4_X5)]
ldp x6, x7, [sp, #(EXCEPTION_CONTEXT_X6_X7)]
ldp x8, x9, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
ldp x10, x11, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
ldp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
ldp x14, x15, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
/* Return. */
add sp, sp, #0x120
add sp, sp, #(EXCEPTION_CONTEXT_SIZE)
eret
4: /* Return from SVC. */
/* Clear our in-SVC note. */
strb wzr, [sp, #(0x120 + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
strb wzr, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_CALLING_SVC)]
/* If we should, trace the svc exit. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING)
@@ -396,16 +396,16 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
#endif
/* Restore registers. */
ldp x8, x9, [sp, #(8 * 8)]
ldp x10, x11, [sp, #(8 * 10)]
ldp x12, x13, [sp, #(8 * 12)]
ldp x14, xzr, [sp, #(8 * 14)]
ldp x17, x20, [sp, #(8 * 32)]
ldr x19, [sp, #(8 * 34)]
ldp x8, x9, [sp, #(EXCEPTION_CONTEXT_X8_X9)]
ldp x10, x11, [sp, #(EXCEPTION_CONTEXT_X10_X11)]
ldp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
ldp x14, xzr, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
msr elr_el1, x17
msr spsr_el1, x20
msr tpidr_el0, x19
/* Return. */
add sp, sp, #0x120
add sp, sp, #(EXCEPTION_CONTEXT_SIZE)
eret

View File

@@ -1437,13 +1437,13 @@ namespace ams::kern::board::nintendo::nx {
return true;
}
Result KDevicePageTable::Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) {
Result KDevicePageTable::Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings) {
/* Clear the output size. */
*out_mapped_size = 0;
/* Map the pages. */
s32 num_pt = 0;
return this->MapImpl(out_mapped_size, num_pt, refresh_mappings ? 1 : std::numeric_limits<s32>::max(), page_table, process_address, size, device_address, device_perm, refresh_mappings);
return this->MapImpl(out_mapped_size, num_pt, refresh_mappings ? 1 : std::numeric_limits<s32>::max(), page_table, process_address, size, device_address, device_perm, is_aligned);
}
Result KDevicePageTable::Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address) {

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* For some reason GAS doesn't know about it, even with .cpu cortex-a57 */
#define cpuactlr_el1 s3_1_c15_c2_0
#define cpuectlr_el1 s3_1_c15_c2_1

View File

@@ -31,10 +31,12 @@ namespace ams::kern {
constinit u64 g_initial_process_id_min = std::numeric_limits<u64>::max();
constinit u64 g_initial_process_id_max = std::numeric_limits<u64>::min();
void LoadInitialProcessBinaryHeader() {
void LoadInitialProcessBinaryHeader(KVirtualAddress virt_addr = Null<KVirtualAddress>) {
if (g_initial_process_binary_header.magic != InitialProcessBinaryMagic) {
/* Get the virtual address for the image. */
const KVirtualAddress virt_addr = GetInitialProcessBinaryAddress();
/* Get the virtual address, if it's not overridden. */
if (virt_addr == Null<KVirtualAddress>) {
virt_addr = GetInitialProcessBinaryAddress();
}
/* Copy and validate the header. */
g_initial_process_binary_header = *GetPointer<InitialProcessBinaryHeader>(virt_addr);
@@ -54,12 +56,16 @@ namespace ams::kern {
/* Attach to the current KIP. */
KInitialProcessReader reader;
MESOSPHERE_ABORT_UNLESS(reader.Attach(current) != Null<KVirtualAddress>);
KVirtualAddress data = reader.Attach(current);
MESOSPHERE_ABORT_UNLESS(data != Null<KVirtualAddress>);
/* If the process uses secure memory, account for that. */
if (reader.UsesSecureMemory()) {
g_initial_process_secure_memory_size += reader.GetSize() + util::AlignUp(reader.GetStackSize(), PageSize);
}
/* Advance to the next KIP. */
current = data + reader.GetBinarySize();
}
}
}
@@ -267,6 +273,10 @@ namespace ams::kern {
}
}
ALWAYS_INLINE KVirtualAddress GetInitialProcessBinaryAddress(KVirtualAddress pool_end) {
return pool_end - InitialProcessBinarySizeMax;
}
}
u64 GetInitialProcessIdMin() {
@@ -283,7 +293,7 @@ namespace ams::kern {
MESOSPHERE_INIT_ABORT_UNLESS(pool_region != nullptr);
MESOSPHERE_INIT_ABORT_UNLESS(pool_region->GetEndAddress() != 0);
MESOSPHERE_ABORT_UNLESS(pool_region->GetSize() >= InitialProcessBinarySizeMax);
return pool_region->GetEndAddress() - InitialProcessBinarySizeMax;
return GetInitialProcessBinaryAddress(pool_region->GetEndAddress());
}
size_t GetInitialProcessesSecureMemorySize() {
@@ -311,6 +321,10 @@ namespace ams::kern {
}
}
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end) {
LoadInitialProcessBinaryHeader(GetInitialProcessBinaryAddress(KMemoryLayout::GetLinearVirtualAddress(pool_end)));
}
void CreateAndRunInitialProcesses() {
/* Allocate space for the processes. */
InitialProcessInfo *infos = static_cast<InitialProcessInfo *>(__builtin_alloca(sizeof(InitialProcessInfo) * g_initial_process_binary_header.num_processes));

View File

@@ -51,7 +51,7 @@ namespace ams::kern {
{
KScopedSchedulerLock sl;
auto it = m_tree.nfind_light({ addr, -1 });
auto it = m_tree.nfind_key({ addr, -1 });
while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
KThread *target_thread = std::addressof(*it);
target_thread->SetSyncedObject(nullptr, ResultSuccess());
@@ -78,7 +78,7 @@ namespace ams::kern {
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
R_UNLESS(user_value == value, svc::ResultInvalidState());
auto it = m_tree.nfind_light({ addr, -1 });
auto it = m_tree.nfind_key({ addr, -1 });
while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
KThread *target_thread = std::addressof(*it);
target_thread->SetSyncedObject(nullptr, ResultSuccess());
@@ -100,7 +100,7 @@ namespace ams::kern {
{
KScopedSchedulerLock sl;
auto it = m_tree.nfind_light({ addr, -1 });
auto it = m_tree.nfind_key({ addr, -1 });
/* Determine the updated value. */
s32 new_value;
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {

View File

@@ -22,19 +22,19 @@ namespace ams::kern {
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
{ .bit_width = 32, .address = 2_MB, .size = 1_GB - 2_MB, .type = KAddressSpaceInfo::Type_MapSmall, },
{ .bit_width = 32, .address = 1_GB, .size = 4_GB - 1_GB, .type = KAddressSpaceInfo::Type_MapLarge, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 36, .address = 128_MB, .size = 2_GB - 128_MB, .type = KAddressSpaceInfo::Type_MapSmall, },
{ .bit_width = 36, .address = 2_GB, .size = 64_GB - 2_GB, .type = KAddressSpaceInfo::Type_MapLarge, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = 128_MB, .size = 512_GB - 128_MB, .type = KAddressSpaceInfo::Type_Map39Bit, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_MapSmall, },
{ .bit_width = 39, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = Invalid, .size = 2_GB, .type = KAddressSpaceInfo::Type_Stack, },
{ 32, 2_MB, 1_GB - 2_MB, KAddressSpaceInfo::Type_MapSmall, },
{ 32, 1_GB, 4_GB - 1_GB, KAddressSpaceInfo::Type_MapLarge, },
{ 32, Invalid, 1_GB, KAddressSpaceInfo::Type_Heap, },
{ 32, Invalid, 1_GB, KAddressSpaceInfo::Type_Alias, },
{ 36, 128_MB, 2_GB - 128_MB, KAddressSpaceInfo::Type_MapSmall, },
{ 36, 2_GB, 64_GB - 2_GB, KAddressSpaceInfo::Type_MapLarge, },
{ 36, Invalid, 6_GB, KAddressSpaceInfo::Type_Heap, },
{ 36, Invalid, 6_GB, KAddressSpaceInfo::Type_Alias, },
{ 39, 128_MB, 512_GB - 128_MB, KAddressSpaceInfo::Type_Map39Bit, },
{ 39, Invalid, 64_GB, KAddressSpaceInfo::Type_MapSmall, },
{ 39, Invalid, 6_GB, KAddressSpaceInfo::Type_Heap, },
{ 39, Invalid, 64_GB, KAddressSpaceInfo::Type_Alias, },
{ 39, Invalid, 2_GB, KAddressSpaceInfo::Type_Stack, },
};
constexpr bool IsAllowedIndexForAddress(size_t index) {

View File

@@ -22,4 +22,35 @@ namespace ams::kern {
return obj;
}
NOINLINE bool KAutoObject::Open() {
MESOSPHERE_ASSERT_THIS();
/* Atomically increment the reference count, only if it's positive. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_relaxed);
do {
if (AMS_UNLIKELY(cur_ref_count == 0)) {
MESOSPHERE_AUDIT(cur_ref_count != 0);
return false;
}
MESOSPHERE_ABORT_UNLESS(cur_ref_count < cur_ref_count + 1);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count + 1, std::memory_order_relaxed));
return true;
}
NOINLINE void KAutoObject::Close() {
MESOSPHERE_ASSERT_THIS();
/* Atomically decrement the reference count, not allowing it to become negative. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_relaxed);
do {
MESOSPHERE_ABORT_UNLESS(cur_ref_count > 0);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1, std::memory_order_relaxed));
/* If ref count hits zero, schedule the object for destruction. */
if (cur_ref_count - 1 == 0) {
this->ScheduleDestruction();
}
}
}

View File

@@ -168,7 +168,7 @@ namespace ams::kern {
{
KScopedSchedulerLock sl;
auto it = m_tree.nfind_light({ cv_key, -1 });
auto it = m_tree.nfind_key({ cv_key, -1 });
while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetConditionVariableKey() == cv_key)) {
KThread *target_thread = std::addressof(*it);

View File

@@ -308,8 +308,11 @@ namespace ams::kern {
}
/* Send an exception event to represent our breaking the process. */
static_assert(util::size(thread_ids) >= 4);
this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerBreak, thread_ids[0], thread_ids[1], thread_ids[2], thread_ids[3]);
/* TODO: How should this be handled in the case of more than 4 physical cores? */
static_assert(util::size(thread_ids) <= 4);
[&]<size_t... Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerBreak, thread_ids[Ix]...);
}(std::make_index_sequence<util::size(thread_ids)>());
/* Signal. */
this->NotifyAvailable();

View File

@@ -86,7 +86,7 @@ namespace ams::kern {
auto mapped_size_guard = SCOPE_GUARD { *out_mapped_size = 0; };
/* Perform the mapping. */
R_TRY(m_table.Map(out_mapped_size, page_table, process_address, size, device_address, device_perm, refresh_mappings));
R_TRY(m_table.Map(out_mapped_size, page_table, process_address, size, device_address, device_perm, is_aligned, refresh_mappings));
/* Ensure that we unmap the pages if we fail to update the protections. */
/* NOTE: Nintendo does not check the result of this unmap call. */

View File

@@ -25,13 +25,18 @@ namespace ams::kern {
constexpr size_t CarveoutAlignment = 0x20000;
constexpr size_t CarveoutSizeMax = 512_MB - CarveoutAlignment;
template<typename... T> requires (std::same_as<T, KMemoryRegionAttr> && ...)
constexpr ALWAYS_INLINE KMemoryRegionType GetMemoryRegionType(KMemoryRegionType base, T... attr) {
return util::FromUnderlying<KMemoryRegionType>(util::ToUnderlying(base) | (util::ToUnderlying<T>(attr) | ...));
}
ALWAYS_INLINE bool SetupUartPhysicalMemoryRegion() {
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART)
switch (KSystemControl::Init::GetDebugLogUartPort()) {
case 0: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 1: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 2: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 3: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 0: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, GetMemoryRegionType(KMemoryRegionType_Uart, KMemoryRegionAttr_ShouldKernelMap));
case 1: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, GetMemoryRegionType(KMemoryRegionType_Uart, KMemoryRegionAttr_ShouldKernelMap));
case 2: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, GetMemoryRegionType(KMemoryRegionType_Uart, KMemoryRegionAttr_ShouldKernelMap));
case 3: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, GetMemoryRegionType(KMemoryRegionType_Uart, KMemoryRegionAttr_ShouldKernelMap));
default: return false;
}
#elif defined(MESOSPHERE_DEBUG_LOG_USE_IRAM_RINGBUFFER)
@@ -43,11 +48,11 @@ namespace ams::kern {
ALWAYS_INLINE bool SetupPowerManagementControllerMemoryRegion() {
/* For backwards compatibility, the PMC must remain mappable on < 2.0.0. */
const auto rtc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : static_cast<KMemoryRegionAttr>(0);
const auto pmc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : KMemoryRegionAttr_ShouldKernelMap;
const KMemoryRegionAttr rtc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : static_cast<KMemoryRegionAttr>(0);
const KMemoryRegionAttr pmc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : KMemoryRegionAttr_ShouldKernelMap;
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, KMemoryRegionType_None | rtc_restrict_attr) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, KMemoryRegionType_PowerManagementController | pmc_restrict_attr);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, GetMemoryRegionType(KMemoryRegionType_None, rtc_restrict_attr)) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, GetMemoryRegionType(KMemoryRegionType_PowerManagementController, pmc_restrict_attr));
}
void InsertPoolPartitionRegionIntoBothTrees(size_t start, size_t size, KMemoryRegionType phys_type, KMemoryRegionType virt_type, u32 &cur_attr) {
@@ -67,29 +72,29 @@ namespace ams::kern {
/* TODO: Give these constexpr defines somewhere? */
MESOSPHERE_INIT_ABORT_UNLESS(SetupUartPhysicalMemoryRegion());
MESOSPHERE_INIT_ABORT_UNLESS(SetupPowerManagementControllerMemoryRegion());
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70019000, 0x1000, KMemoryRegionType_MemoryController | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001C000, 0x1000, KMemoryRegionType_MemoryController0 | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001D000, 0x1000, KMemoryRegionType_MemoryController1 | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50040000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50041000, 0x1000, KMemoryRegionType_InterruptDistributor | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50042000, 0x1000, KMemoryRegionType_InterruptCpuInterface | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50043000, 0x1D000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70019000, 0x1000, GetMemoryRegionType(KMemoryRegionType_MemoryController, KMemoryRegionAttr_NoUserMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001C000, 0x1000, GetMemoryRegionType(KMemoryRegionType_MemoryController0, KMemoryRegionAttr_NoUserMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001D000, 0x1000, GetMemoryRegionType(KMemoryRegionType_MemoryController1, KMemoryRegionAttr_NoUserMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50040000, 0x1000, GetMemoryRegionType(KMemoryRegionType_None, KMemoryRegionAttr_NoUserMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50041000, 0x1000, GetMemoryRegionType(KMemoryRegionType_InterruptDistributor, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50042000, 0x1000, GetMemoryRegionType(KMemoryRegionType_InterruptCpuInterface, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50043000, 0x1D000, GetMemoryRegionType(KMemoryRegionType_None, KMemoryRegionAttr_NoUserMap)));
/* Map IRAM unconditionally, to support debug-logging-to-iram build config. */
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x40000000, 0x40000, KMemoryRegionType_LegacyLpsIram | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x40000000, 0x40000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsIram, KMemoryRegionAttr_ShouldKernelMap)));
if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
/* Prevent mapping the bpmp exception vectors or the ipatch region. */
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6001DC00, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, GetMemoryRegionType(KMemoryRegionType_None, KMemoryRegionAttr_NoUserMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6001DC00, 0x400, GetMemoryRegionType(KMemoryRegionType_None, KMemoryRegionAttr_NoUserMap)));
} else {
/* Map devices required for legacy lps driver. */
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, KMemoryRegionType_LegacyLpsExceptionVectors | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60007000, 0x1000, KMemoryRegionType_LegacyLpsFlowController | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60004000, 0x1000, KMemoryRegionType_LegacyLpsPrimaryICtlr | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60001000, 0x1000, KMemoryRegionType_LegacyLpsSemaphore | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70016000, 0x1000, KMemoryRegionType_LegacyLpsAtomics | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60006000, 0x1000, KMemoryRegionType_LegacyLpsClkRst | KMemoryRegionAttr_ShouldKernelMap));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsExceptionVectors, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60007000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsFlowController, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60004000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsPrimaryICtlr, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60001000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsSemaphore, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70016000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsAtomics, KMemoryRegionAttr_ShouldKernelMap)));
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60006000, 0x1000, GetMemoryRegionType(KMemoryRegionType_LegacyLpsClkRst, KMemoryRegionAttr_ShouldKernelMap)));
}
}
@@ -185,6 +190,12 @@ namespace ams::kern {
static_assert(KMemoryManager::Pool_Unsafe == KMemoryManager::Pool_Application);
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
/* NOTE: Beginning with 12.0.0 (and always, in mesosphere), the initial process binary is at the end of the pool region. */
/* However, this is problematic for < 5.0.0, because we require the initial process binary to be parsed in order */
/* to determine the pool sizes. Hence, we will force an initial binary load with the known pool end directly, so */
/* that we retain compatibility with lower firmware versions. */
LoadInitialProcessBinaryHeaderDeprecated(pool_end);
/* Get Secure pool size. */
const size_t secure_pool_size = [] ALWAYS_INLINE_LAMBDA (auto target_firmware) -> size_t {
constexpr size_t LegacySecureKernelSize = 8_MB; /* KPageBuffer pages, other small kernel allocations. */

View File

@@ -148,11 +148,7 @@ namespace ams::kern {
}
}
void KMemoryLayout::InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start) {
/* Set static differences. */
s_linear_phys_to_virt_diff = GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start);
s_linear_virt_to_phys_diff = GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start);
void KMemoryLayout::InitializeLinearMemoryRegionTrees() {
/* Initialize linear trees. */
for (auto &region : GetPhysicalMemoryRegionTree()) {
if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {

View File

@@ -108,6 +108,7 @@ namespace ams::kern {
R_UNLESS(m_current_values[which] <= value, svc::ResultInvalidState());
m_limit_values[which] = value;
m_peak_values[which] = m_current_values[which];
return ResultSuccess();
}

View File

@@ -231,6 +231,10 @@ namespace ams::kern {
next_thread = m_idle_thread;
}
if (next_thread->GetCurrentCore() != m_core_id) {
next_thread->SetCurrentCore(m_core_id);
}
/* If we're not actually switching thread, there's nothing to do. */
if (next_thread == cur_thread) {
return;
@@ -263,10 +267,6 @@ namespace ams::kern {
MESOSPHERE_KTRACE_THREAD_SWITCH(next_thread);
if (next_thread->GetCurrentCore() != m_core_id) {
next_thread->SetCurrentCore(m_core_id);
}
/* Switch the current process, if we're switching processes. */
if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) {
KProcess::Switch(cur_process, next_process);

View File

@@ -436,7 +436,7 @@ namespace ams::kern {
/* Disallow performing thread suspension. */
{
/* Update our allow flags. */
m_suspend_allowed_flags &= ~(1 << (SuspendType_Thread + ThreadState_SuspendShift));
m_suspend_allowed_flags &= ~(1 << (util::ToUnderlying(SuspendType_Thread) + util::ToUnderlying(ThreadState_SuspendShift)));
/* Update our state. */
this->UpdateState();
@@ -485,7 +485,7 @@ namespace ams::kern {
/* Allow performing thread suspension (if termination hasn't been requested). */
if (!this->IsTerminationRequested()) {
/* Update our allow flags. */
m_suspend_allowed_flags |= (1 << (SuspendType_Thread + ThreadState_SuspendShift));
m_suspend_allowed_flags |= (1 << (util::ToUnderlying(SuspendType_Thread) + util::ToUnderlying(ThreadState_SuspendShift)));
/* Update our state. */
this->UpdateState();
@@ -760,7 +760,7 @@ namespace ams::kern {
KScopedSchedulerLock lk;
/* Note the request in our flags. */
m_suspend_request_flags |= (1u << (ThreadState_SuspendShift + type));
m_suspend_request_flags |= (1u << (util::ToUnderlying(ThreadState_SuspendShift) + util::ToUnderlying(type)));
/* Try to perform the suspend. */
this->TrySuspend();
@@ -772,7 +772,7 @@ namespace ams::kern {
KScopedSchedulerLock sl;
/* Clear the request in our flags. */
m_suspend_request_flags &= ~(1u << (ThreadState_SuspendShift + type));
m_suspend_request_flags &= ~(1u << (util::ToUnderlying(ThreadState_SuspendShift) + util::ToUnderlying(type)));
/* Update our state. */
this->UpdateState();

View File

@@ -124,6 +124,7 @@ $(OFILES_SRC) : $(HFILES_BIN)
ams_environment_weak.o: CXXFLAGS += -fno-lto
pm_info_api_weak.o: CXXFLAGS += -fno-lto
hos_stratosphere_api.o: CXXFLAGS += -fno-lto
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin

View File

@@ -20,14 +20,7 @@ namespace ams::dd {
using ProcessHandle = ::Handle;
/* TODO gcc-11: using MemoryPermission = os::MemoryPermission; using enum os::MemoryPermission; */
enum MemoryPermission {
MemoryPermission_None = 0,
MemoryPermission_ReadOnly = (1u << 0),
MemoryPermission_WriteOnly = (1u << 1),
MemoryPermission_ReadWrite = MemoryPermission_ReadOnly | MemoryPermission_WriteOnly,
};
using MemoryPermission = os::MemoryPermission;
using enum os::MemoryPermission;
}

View File

@@ -26,8 +26,8 @@
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0) \
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) \
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \

View File

@@ -22,8 +22,9 @@ namespace ams::erpt::srv {
constexpr inline const char ReportOnSdStoragePath[] = "ersd";
constexpr inline const char ReportStoragePath[] = "save";
constexpr inline const char JournalFileName[] = "save:/journal";
constexpr inline const char ReportStoragePath[] = "save";
constexpr inline const char JournalFileName[] = "save:/journal";
constexpr inline const char ForcedShutdownContextFileName[] = "save:/forced-shutdown";
constexpr size_t ReportFileNameLength = 64;
constexpr size_t AttachmentFileNameLength = 64;

View File

@@ -16,4 +16,6 @@
#pragma once
#include <stratosphere/err/err_types.hpp>
#include <stratosphere/err/err_error_context.hpp>
#include <stratosphere/err/err_system_api.hpp>

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/err/err_types.hpp>
namespace ams::err {
ErrorCode ConvertResultToErrorCode(const Result &result);
void GetErrorCodeString(char *dst, size_t dst_size, ErrorCode error_code);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::err {
using ErrorCodeCategory = u32;
using ErrorCodeNumber = u32;
struct ErrorCode {
static constexpr auto StringLengthMax = 15;
ErrorCodeCategory category;
ErrorCodeNumber number;
constexpr ALWAYS_INLINE bool IsValid() const { return this->category > 0; }
};
constexpr inline ErrorCode InvalidErrorCode = {
.category = 0,
.number = 0,
};
}

View File

@@ -68,7 +68,7 @@ namespace ams::fs {
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
switch (op_id) {
case OperationId::InvalidateCache:
case OperationId::Invalidate:
return ResultSuccess();
case OperationId::QueryRange:
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());

View File

@@ -18,11 +18,16 @@
namespace ams::fs {
enum class OperationId : u64 {
Clear = ::FsOperationId_Clear,
ClearSignature = ::FsOperationId_ClearSignature,
InvalidateCache = ::FsOperationId_InvalidateCache,
QueryRange = ::FsOperationId_QueryRange,
enum class OperationId : s64 {
FillZero = 0,
DestroySignature = 1,
Invalidate = 2,
QueryRange = 3,
QueryUnpreparedRange = 4,
QueryLazyLoadCompletionRate = 5,
SetLazyLoadPriority = 6,
ReadLazyLoadFileForciblyForDebug = 10001,
};
}

View File

@@ -55,7 +55,7 @@ namespace ams::fs {
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
switch (op_id) {
case OperationId::InvalidateCache:
case OperationId::Invalidate:
case OperationId::QueryRange:
return this->base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
default:

View File

@@ -20,23 +20,23 @@ namespace ams::fs::impl {
class Newable {
public:
static void *operator new(size_t size) {
static ALWAYS_INLINE void *operator new(size_t size) noexcept {
return ::ams::fs::impl::Allocate(size);
}
static void *operator new(size_t size, Newable *placement) {
static ALWAYS_INLINE void *operator new(size_t size, Newable *placement) noexcept {
return placement;
}
static void *operator new[](size_t size) {
static ALWAYS_INLINE void *operator new[](size_t size) noexcept {
return ::ams::fs::impl::Allocate(size);
}
static void operator delete(void *ptr, size_t size) {
static ALWAYS_INLINE void operator delete(void *ptr, size_t size) noexcept {
return ::ams::fs::impl::Deallocate(ptr, size);
}
static void operator delete[](void *ptr, size_t size) {
static ALWAYS_INLINE void operator delete[](void *ptr, size_t size) noexcept {
return ::ams::fs::impl::Deallocate(ptr, size);
}
};

View File

@@ -18,6 +18,7 @@
#include <stratosphere/fssrv/sf/fssrv_sf_path.hpp>
#include <stratosphere/fssrv/sf/fssrv_sf_ifile.hpp>
#include <stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp>
#include <stratosphere/fssrv/impl/fssrv_impl_program_index_map_info_manager.hpp>
#include <stratosphere/fssrv/fssrv_path_normalizer.hpp>
#include <stratosphere/fssrv/fssrv_nca_crypto_configuration.hpp>
#include <stratosphere/fssrv/fssrv_memory_resource_from_standard_allocator.hpp>

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ncm/ncm_ids.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
#include <stratosphere/fs/fs_program_index_map_info.hpp>
namespace ams::fssrv::impl {
struct ProgramIndexMapInfoEntry : public ::ams::util::IntrusiveListBaseNode<ProgramIndexMapInfoEntry>, public ::ams::fs::impl::Newable {
ncm::ProgramId program_id;
ncm::ProgramId base_program_id;
u8 program_index;
};
class ProgramIndexMapInfoManager {
NON_COPYABLE(ProgramIndexMapInfoManager);
NON_MOVEABLE(ProgramIndexMapInfoManager);
private:
using ProgramIndexMapInfoList = util::IntrusiveListBaseTraits<ProgramIndexMapInfoEntry>::ListType;
private:
ProgramIndexMapInfoList m_list;
mutable os::SdkMutex m_mutex;
public:
constexpr ProgramIndexMapInfoManager() : m_list(), m_mutex() { /* ... */ }
void Clear() {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
/* Actually clear. */
this->ClearImpl();
}
size_t GetProgramCount() const {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
/* Get the size. */
return m_list.size();
}
std::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
/* Get the entry from the map. */
return this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
return entry.program_id == program_id;
});
}
ncm::ProgramId GetProgramId(const ncm::ProgramId &program_id, u8 program_index) const {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
/* Get the program info for the desired program id. */
const auto base_info = this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
return entry.program_id == program_id;
});
/* Check that an entry exists for the program id. */
if (!base_info.has_value()) {
return ncm::InvalidProgramId;
}
/* Get a program info which matches the same base program with the desired index. */
const auto target_info = this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
return entry.base_program_id == base_info->base_program_id && entry.program_index == program_index;
});
/* Return the desired program id. */
if (target_info.has_value()) {
return target_info->program_id;
} else {
return ncm::InvalidProgramId;
}
}
Result Reset(const fs::ProgramIndexMapInfo *infos, int count) {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
/* Clear the map, and ensure we remain clear if we fail after this point. */
this->ClearImpl();
auto clear_guard = SCOPE_GUARD { this->ClearImpl(); };
/* Add each info to the list. */
for (int i = 0; i < count; ++i) {
/* Allocate new entry. */
auto *entry = new ProgramIndexMapInfoEntry;
R_UNLESS(entry != nullptr, fs::ResultAllocationFailureInNew());
/* Copy over the info. */
entry->program_id = infos[i].program_id;
entry->base_program_id = infos[i].base_program_id;
entry->program_index = infos[i].program_index;
/* Add to the list. */
m_list.push_back(*entry);
}
/* We successfully imported the map. */
clear_guard.Cancel();
return ResultSuccess();
}
private:
void ClearImpl() {
/* Delete all entries. */
while (!m_list.empty()) {
/* Get the first entry. */
ProgramIndexMapInfoEntry *front = std::addressof(*m_list.begin());
/* Erase it from the list. */
m_list.erase(m_list.iterator_to(*front));
/* Delete the entry. */
delete front;
}
}
template<typename F>
std::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const {
/* Try to find an entry matching the predicate. */
std::optional<fs::ProgramIndexMapInfo> match = std::nullopt;
for (const auto &entry : m_list) {
/* If the predicate matches, we want to return the relevant info. */
if (f(entry)) {
match.emplace();
match->program_id = entry.program_id;
match->base_program_id = entry.base_program_id;
match->program_index = entry.program_index;
break;
}
}
return match;
}
};
}

View File

@@ -106,11 +106,9 @@ namespace ams::fssystem {
using Newable::operator new;
using Newable::operator delete;
static void *operator new(size_t, void *p) {
return p;
}
static void operator delete(void *, size_t, void*) { /* ... */ }
static ALWAYS_INLINE void *operator new(size_t, void *p) noexcept { return p; }
static ALWAYS_INLINE void operator delete(void *, size_t, void*) noexcept { /* ... */ }
};
using AttrListTraits = util::IntrusiveListBaseTraits<AttrInfo>;

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