Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9df13781c2 | ||
|
|
283736878d | ||
|
|
f863164648 | ||
|
|
3eb76fcd16 | ||
|
|
2088c5a34a | ||
|
|
846cde52e0 | ||
|
|
a3dd445b32 | ||
|
|
c362838e11 | ||
|
|
e086022b77 | ||
|
|
70c1bad08b | ||
|
|
38f9a76ba0 | ||
|
|
4892ffae15 | ||
|
|
25305257d6 | ||
|
|
e423aef033 | ||
|
|
8a6afe7909 | ||
|
|
c02f32f1bf | ||
|
|
2ab01ad33c | ||
|
|
3dbc79dd5c | ||
|
|
90b54c03b3 | ||
|
|
7821241356 | ||
|
|
8fea8d9b2e | ||
|
|
dcdf46f576 | ||
|
|
df5537b748 | ||
|
|
0f2855ada8 | ||
|
|
c790d03693 | ||
|
|
25be7c5b1b | ||
|
|
7e05e12b83 | ||
|
|
99d7f72c51 | ||
|
|
691a453d77 | ||
|
|
88246f475c | ||
|
|
269d4496b2 | ||
|
|
bb4c7a390b | ||
|
|
b846628362 | ||
|
|
26fb201518 | ||
|
|
01ce7cef14 | ||
|
|
3f3aaa01fa | ||
|
|
bf8de39e69 | ||
|
|
6bb4253df5 | ||
|
|
cfd7121574 | ||
|
|
972681c57e | ||
|
|
0a11cbc2d6 | ||
|
|
32f487abfb | ||
|
|
7d61cab01c | ||
|
|
14ed4e4057 | ||
|
|
e8ba632606 | ||
|
|
dbcb1e1564 | ||
|
|
15381409dc | ||
|
|
10ad6934ac | ||
|
|
03e66efd85 | ||
|
|
7040e8976d | ||
|
|
296a6af058 | ||
|
|
2c332d1cf8 | ||
|
|
243d7dc777 | ||
|
|
355010ad84 | ||
|
|
ef0c15b764 | ||
|
|
0dc308d92a | ||
|
|
eb5542963f | ||
|
|
18673d96cb | ||
|
|
36f6bdc3a0 | ||
|
|
d6fff49845 | ||
|
|
d05e8fb23a | ||
|
|
0767d9f8da | ||
|
|
21f3d29df7 | ||
|
|
4f16106702 | ||
|
|
19be54ff95 | ||
|
|
ed80d6ec8c | ||
|
|
57b6c71c1c | ||
|
|
0a11d341b7 | ||
|
|
8010290472 | ||
|
|
fbc526d163 | ||
|
|
5bb790e4a7 | ||
|
|
0a6219e6e0 | ||
|
|
037b04ac60 | ||
|
|
9e563d590b | ||
|
|
bdcf02a3ef | ||
|
|
88ac85c423 | ||
|
|
2e1a93f1d1 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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?
|
||||
|
||||
|
||||
1
Makefile
1
Makefile
@@ -43,6 +43,7 @@ libraries:
|
||||
|
||||
clean:
|
||||
$(MAKE) -C fusee clean
|
||||
$(MAKE) -C emummc clean
|
||||
rm -rf out
|
||||
|
||||
dist-no-debug: all
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,42 @@
|
||||
# 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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
201
emummc/emummc.ld
Normal 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
8
emummc/emummc.specs
Normal 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
60
emummc/source/FS/offsets/1203.h
Normal file
60
emummc/source/FS/offsets/1203.h
Normal 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__
|
||||
60
emummc/source/FS/offsets/1203_exfat.h
Normal file
60
emummc/source/FS/offsets/1203_exfat.h
Normal 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__
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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 :=
|
||||
|
||||
|
||||
@@ -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 :=
|
||||
|
||||
|
||||
@@ -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 :=
|
||||
|
||||
|
||||
@@ -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 :=
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = 86c2eec8e9e966a30c19692adb79faeda45c1940
|
||||
parent = aa2d03d8e13bc5d3f34751b6105503a601dc958e
|
||||
commit = eb667fea5142fd35caf539289603748dd6f4f87e
|
||||
parent = 283736878ddf2cf1cad731b4bf21f916c7e87054
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
cmdver = 0.4.0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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'>;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
namespace ams::kern::init {
|
||||
|
||||
static_assert(util::IsPowerOfTwo(alignof(KInitArguments)) && util::IsPowerOfTwo(sizeof(KInitArguments)));
|
||||
|
||||
KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -37,4 +37,6 @@ namespace ams::kern {
|
||||
KVirtualAddress GetInitialProcessBinaryAddress();
|
||||
size_t GetInitialProcessesSecureMemorySize();
|
||||
|
||||
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end);
|
||||
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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) { /* ... */ }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 ®ion : GetPhysicalMemoryRegionTree()) {
|
||||
if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user