Compare commits

..

3 Commits
pgl ... erpt

Author SHA1 Message Date
Michael Scire
8e1cf7a7e0 erpt: amend logic for culling orphan attachments 2020-04-12 18:39:03 -07:00
Michael Scire
6b3bf10e46 fatal: update for latest bindings 2020-04-12 18:30:15 -07:00
Michael Scire
16a25309d2 erpt: reimplement the sysmodule 2020-04-11 21:40:14 -07:00
207 changed files with 743 additions and 5003 deletions

View File

@@ -58,7 +58,6 @@ dist-no-debug: all
mkdir atmosphere-$(AMSVER)/switch mkdir atmosphere-$(AMSVER)/switch
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008 mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032 mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034 mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036 mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036
@@ -83,7 +82,6 @@ dist-no-debug: all
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B/exefs.nsp
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp
@@ -135,7 +133,6 @@ dist: dist-no-debug
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../; cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)-debug rm -r atmosphere-$(AMSVER)-debug
mv atmosphere-$(AMSVER)-debug.zip out/atmosphere-$(AMSVER)-debug.zip mv atmosphere-$(AMSVER)-debug.zip out/atmosphere-$(AMSVER)-debug.zip

View File

@@ -1,34 +1,4 @@
# Changelog # Changelog
## 0.11.1
+ A bug was fixed that could cause owls to flicker under certain circumstances.
+ For those interested in technical details, in 10.0.0 kernelldr/kernel no longer set cpuactlr_el1, assuming that it was set correctly by the secure monitor.
+ However, exosphere did not set cpuactlr_el1. This meant that the register held the reset value going into boot.
+ This caused a variety of highly erratic symptoms, including causing basically any game to crash seemingly randomly.
+ A number of other major inaccuracies in exosphere were corrected.
+ General system stability improvements to enhance the user's experience.
## 0.11.0
+ Support was added for 10.0.0.
+ Exosphere has been updated to reflect the new key import semantics in 10.0.0.
+ kernel_ldr now implements physical ASLR for the kernel's backing pages.
+ Loader, NCM, and PM have been updated to reflect the changes Nintendo made in 10.0.0.
+ Creport was updated to use the new `pgl` service to terminate processes instead of `ns:dev`.
+ A reimplementation of the `erpt` (error reports) system module was added.
+ In previous versions of Atmosphere, a majority of error reports were prevented via a combination of custom creport, fatal, and stubbed eclct.
+ However, error reports were still generated via some system actions.
+ Most notably, any time the error applet appeared, an error report was generated.
+ By default, atmosphere disabled the *uploading* of error reports, but going online in OFW after an error report occurred in Atmosphere could lead to undesirable telemetry.
+ Atmosphere's `erpt` reimplementation allows the system to interact with existing error reports as expected.
+ However, all new error reports are instead saved to the sd card (`/atmosphere/erpt_reports`), and are not committed to the system savegame.
+ Users curious about what kind of telemetry is being prevented can view the reports as they're generated in there.
+ Reports are saved as msgpack (as this is what Nintendo uses).
+ Please note, not all telemetry is disabled. Play reports and System reports will continue to function unmodified.
+ With atmosphere's `erpt` implementation, homebrew can now use the native error applet to display errors without worrying about generating undesirable telemetry.
+ libstratosphere and libvapours received a number of improvements.
+ With thanks to @Adubbz for his work, the NCM namespace now has client code.
+ This lays the groundwork for first-class system update/downgrade homebrew support in the near future.
+ In particular, code implementing the os namespace is significantly more accurate.
+ In addition, Nintendo's allocators were implemented, allowing for identical memory efficiency versus Nintendo's implementations.
+ General system stability improvements to enhance the user's experience.
## 0.10.5 ## 0.10.5
+ Changes were made to the way fs.mitm builds images when providing a layeredfs romfs. + Changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
+ Building romfs metadata previously had a memory cost of about ~4-5x the file table size. + Building romfs metadata previously had a memory cost of about ~4-5x the file table size.

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/m4xw/emuMMC remote = https://github.com/m4xw/emuMMC
branch = develop branch = develop
commit = b168ddf5fbb31013ff529a4859110c82b11eb361 commit = d12dd5464422029a1e5601916517ec3f1c81d8d0
parent = c07f54f3709a4710e0aead6c91139fa0893b5e5c parent = 259a1a7513236a1de4d373bc6cb99032ede2c626
method = rebase method = rebase
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -2,7 +2,7 @@
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions ### Supported Horizon Versions
**1.0.0 - 10.0.0** **1.0.0 - 9.1.0**
## Features ## Features
* Arbitrary SDMMC backend selection * Arbitrary SDMMC backend selection

View File

@@ -45,8 +45,6 @@
#include "offsets/900_exfat.h" #include "offsets/900_exfat.h"
#include "offsets/910.h" #include "offsets/910.h"
#include "offsets/910_exfat.h" #include "offsets/910_exfat.h"
#include "offsets/1000.h"
#include "offsets/1000_exfat.h"
#include "../utils/fatal.h" #include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -102,8 +100,6 @@ DEFINE_OFFSET_STRUCT(_900);
DEFINE_OFFSET_STRUCT(_900_EXFAT); DEFINE_OFFSET_STRUCT(_900_EXFAT);
DEFINE_OFFSET_STRUCT(_910); DEFINE_OFFSET_STRUCT(_910);
DEFINE_OFFSET_STRUCT(_910_EXFAT); DEFINE_OFFSET_STRUCT(_910_EXFAT);
DEFINE_OFFSET_STRUCT(_1000);
DEFINE_OFFSET_STRUCT(_1000_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) { const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) { switch (version) {
@@ -165,10 +161,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_910)); return &(GET_OFFSET_STRUCT_NAME(_910));
case FS_VER_9_1_0_EXFAT: case FS_VER_9_1_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_910_EXFAT)); return &(GET_OFFSET_STRUCT_NAME(_910_EXFAT));
case FS_VER_10_0_0:
return &(GET_OFFSET_STRUCT_NAME(_1000));
case FS_VER_10_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1000_EXFAT));
default: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -65,9 +65,6 @@ enum FS_VER
FS_VER_9_1_0, FS_VER_9_1_0,
FS_VER_9_1_0_EXFAT, FS_VER_9_1_0_EXFAT,
FS_VER_10_0_0,
FS_VER_10_0_0_EXFAT,
FS_VER_MAX, FS_VER_MAX,
}; };

View File

@@ -1,58 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_1000_H__
#define __FS_1000_H__
// Accessor vtable getters
#define FS_OFFSET_1000_SDMMC_ACCESSOR_GC 0x14DC90
#define FS_OFFSET_1000_SDMMC_ACCESSOR_SD 0x14BDA0
#define FS_OFFSET_1000_SDMMC_ACCESSOR_NAND 0x146C20
// Hooks
#define FS_OFFSET_1000_SDMMC_WRAPPER_READ 0x142380
#define FS_OFFSET_1000_SDMMC_WRAPPER_WRITE 0x142460
#define FS_OFFSET_1000_RTLD 0x634
#define FS_OFFSET_1000_RTLD_DESTINATION 0x9C
#define FS_OFFSET_1000_CLKRST_SET_MIN_V_CLK_RATE 0x1415A0
// Misc funcs
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data
#define FS_OFFSET_1000_SD_MUTEX 0xE273E8
#define FS_OFFSET_1000_NAND_MUTEX 0xE22DA0
#define FS_OFFSET_1000_ACTIVE_PARTITION 0xE22DE0
#define FS_OFFSET_1000_SDMMC_DAS_HANDLE 0xE0AB90
// NOPs
#define FS_OFFSET_1000_SD_DAS_INIT 0x151CEC
// Nintendo Paths
#define FS_OFFSET_1000_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1000_H__

View File

@@ -1,58 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_1000_EXFAT_H__
#define __FS_1000_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_GC 0x14DC90
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_SD 0x14BDA0
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_NAND 0x146C20
// Hooks
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_READ 0x142380
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_WRITE 0x142460
#define FS_OFFSET_1000_EXFAT_RTLD 0x634
#define FS_OFFSET_1000_EXFAT_RTLD_DESTINATION 0x9C
#define FS_OFFSET_1000_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1415A0
// Misc funcs
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data
#define FS_OFFSET_1000_EXFAT_SD_MUTEX 0xE353E8
#define FS_OFFSET_1000_EXFAT_NAND_MUTEX 0xE30DA0
#define FS_OFFSET_1000_EXFAT_ACTIVE_PARTITION 0xE30DE0
#define FS_OFFSET_1000_EXFAT_SDMMC_DAS_HANDLE 0xE18B90
// NOPs
#define FS_OFFSET_1000_EXFAT_SD_DAS_INIT 0x151CEC
// Nintendo Paths
#define FS_OFFSET_1000_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1000_EXFAT_H__

View File

@@ -36,6 +36,7 @@ sdmmc_storage_t sd_storage;
// init vars // init vars
bool custom_driver = true; bool custom_driver = true;
extern const volatile emuMMC_ctx_t emuMMC_ctx;
// FS funcs // FS funcs
_sdmmc_accessor_gc sdmmc_accessor_gc; _sdmmc_accessor_gc sdmmc_accessor_gc;
@@ -343,7 +344,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id)
{ {
return 0; return 0;
} }
if (mmc_id == FS_SDMMC_EMMC) if (mmc_id == FS_SDMMC_EMMC)
{ {
// Close file handles and unmount // Close file handles and unmount

View File

@@ -50,18 +50,8 @@ extern "C" {
* @return Result code. * @return Result code.
* @note Syscall number 0x55. * @note Syscall number 0x55.
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping.
*/ */
Result svcQueryIoMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size); Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
/**
* @brief Returns a virtual address mapped to a given IO range.
* @return Result code.
* @note Syscall number 0x55.
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping.
*/
Result svcLegacyQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
/** /**
* @brief Attaches a device address space to a device. * @brief Attaches a device address space to a device.

View File

@@ -17,15 +17,6 @@
.endm .endm
SVC_BEGIN svcQueryIoMapping SVC_BEGIN svcQueryIoMapping
STP X0, X1, [SP, #-16]!
SVC 0x55
LDP X3, X4, [SP], #16
STR X1, [X3]
STR X2, [X4]
RET
SVC_END
SVC_BEGIN svcLegacyQueryIoMapping
STR X0, [SP, #-16]! STR X0, [SP, #-16]!
SVC 0x55 SVC 0x55
LDR X2, [SP], #16 LDR X2, [SP], #16

View File

@@ -25,12 +25,11 @@ enum FatalReason
Fatal_InvalidAccessor, Fatal_InvalidAccessor,
Fatal_ReadNoAccessor, Fatal_ReadNoAccessor,
Fatal_WriteNoAccessor, Fatal_WriteNoAccessor,
Fatal_IoMappingLegacy, Fatal_IoMapping,
Fatal_UnknownVersion, Fatal_UnknownVersion,
Fatal_BadResult, Fatal_BadResult,
Fatal_GetConfig, Fatal_GetConfig,
Fatal_CloseAccessor, Fatal_CloseAccessor,
Fatal_IoMapping,
Fatal_Max Fatal_Max
}; };

View File

@@ -38,15 +38,8 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
u64 vaddr; u64 vaddr;
u64 aligned_addr = (io_addr & ~0xFFFul); u64 aligned_addr = (io_addr & ~0xFFFul);
u64 aligned_size = io_size + (io_addr - aligned_addr); u64 aligned_size = io_size + (io_addr - aligned_addr);
if (emuMMC_ctx.fs_ver >= FS_VER_10_0_0) { if (svcQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
u64 out_size; fatal_abort(Fatal_IoMapping);
if (svcQueryIoMapping(&vaddr, &out_size, aligned_addr, aligned_size) != 0) {
fatal_abort(Fatal_IoMapping);
}
} else {
if (svcLegacyQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
fatal_abort(Fatal_IoMappingLegacy);
}
} }
return (uintptr_t)(vaddr + (io_addr - aligned_addr)); return (uintptr_t)(vaddr + (io_addr - aligned_addr));
} }

View File

@@ -19,7 +19,6 @@
#define _UTIL_H_ #define _UTIL_H_
#include "types.h" #include "types.h"
#include "../emuMMC/emummc_ctx.h"
intptr_t QueryIoMapping(u64 addr, u64 size); intptr_t QueryIoMapping(u64 addr, u64 size);
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \ #define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
@@ -38,6 +37,4 @@ void usleep(u64 ticks);
void msleep(u64 milliseconds); void msleep(u64 milliseconds);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
extern volatile emuMMC_ctx_t emuMMC_ctx;
#endif #endif

View File

@@ -263,20 +263,19 @@ uint32_t fuse_get_5x_key_generation(void) {
/* Returns the fuse version expected for the firmware. */ /* Returns the fuse version expected for the firmware. */
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) { uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = { static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1, [ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2, [ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3, [ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */ /* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5, [ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6, [ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7, [ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8, [ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9, [ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9, [ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10, [ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11, [ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12, [ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
[ATMOSPHERE_TARGET_FIRMWARE_1000] = 13,
}; };
if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) { if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) {

View File

@@ -1,32 +0,0 @@
/*
* 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/>.
*/
#ifndef EXOSPHERE_MC0_H
#define EXOSPHERE_MC0_H
#include <stdint.h>
#include "memory_map.h"
/* Exosphere driver for the Tegra X1 MC0. */
static inline uintptr_t get_mc0_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC0);
}
#define MC0_BASE (get_mc0_base())
#define MAKE_MC0_REG(n) MAKE_REG32(MC0_BASE + n)
#endif

View File

@@ -1,32 +0,0 @@
/*
* 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/>.
*/
#ifndef EXOSPHERE_MC0_H
#define EXOSPHERE_MC0_H
#include <stdint.h>
#include "memory_map.h"
/* Exosphere driver for the Tegra X1 MC1. */
static inline uintptr_t get_mc1_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC1);
}
#define MC1_BASE (get_mc1_base())
#define MAKE_MC1_REG(n) MAKE_REG32(MC1_BASE + n)
#endif

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EXOSPHERE_MEMORY_MAP_H #ifndef EXOSPHERE_MEMORY_MAP_H
#define EXOSPHERE_MEMORY_MAP_H #define EXOSPHERE_MEMORY_MAP_H
@@ -48,11 +48,9 @@
#define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */ #define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */
#define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */ #define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */
#define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */ #define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */
#define _MMAPDEV18 ( 0x7001C000ull, 0x1000ull, true ) /* MC0 */ #define _MMAPDEV18 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */
#define _MMAPDEV19 ( 0x7001D000ull, 0x1000ull, true ) /* MC1 */ #define _MMAPDEV19 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
#define _MMAPDEV20 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */ #define _MMAPDEV20 ( 0x40038000ull, 0x5000ull, true ) /* DEBUG: IRAM */
#define _MMAPDEV21 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
#define _MMAPDEV22 ( 0x40038000ull, 0x1000ull, true ) /* DEBUG: IRAM */
/* MMIO 7.0.0+. (addr). */ /* MMIO 7.0.0+. (addr). */
#define _MMAPDEV7X0 ( 0x50041000ull ) /* ARM Interrupt Distributor */ #define _MMAPDEV7X0 ( 0x50041000ull ) /* ARM Interrupt Distributor */
@@ -73,11 +71,9 @@
#define _MMAPDEV7X15 ( 0x6000D000ull ) /* GPIO-1 - GPIO-8 */ #define _MMAPDEV7X15 ( 0x6000D000ull ) /* GPIO-1 - GPIO-8 */
#define _MMAPDEV7X16 ( 0x7000C000ull ) /* I2C-I2C4 */ #define _MMAPDEV7X16 ( 0x7000C000ull ) /* I2C-I2C4 */
#define _MMAPDEV7X17 ( 0x6000F000ull ) /* Exception vectors */ #define _MMAPDEV7X17 ( 0x6000F000ull ) /* Exception vectors */
#define _MMAPDEV7X18 ( 0x7001C000ull ) /* MC0 */ #define _MMAPDEV7X18 ( 0x00000000ull ) /* AMS irampage, NOT mapped at startup */
#define _MMAPDEV7X19 ( 0x7001D000ull ) /* MC1 */ #define _MMAPDEV7X19 ( 0x00000000ull ) /* AMS userpage, NOT mapped at startup */
#define _MMAPDEV7X20 ( 0x00000000ull ) /* AMS irampage, NOT mapped at startup */ #define _MMAPDEV7X20 ( 0x40038000ull ) /* DEBUG: IRAM */
#define _MMAPDEV7X21 ( 0x00000000ull ) /* AMS userpage, NOT mapped at startup */
#define _MMAPDEV7X22 ( 0x40038000ull ) /* DEBUG: IRAM */
/* LP0 entry ram segments (addr, size, additional attributes) */ /* LP0 entry ram segments (addr, size, additional attributes) */
#define _MMAPLP0ES0 ( 0x40020000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM */ #define _MMAPLP0ES0 ( 0x40020000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM */
@@ -137,12 +133,10 @@
#define MMIO_DEVID_GPIO 15 #define MMIO_DEVID_GPIO 15
#define MMIO_DEVID_DTV_I2C234 16 #define MMIO_DEVID_DTV_I2C234 16
#define MMIO_DEVID_EXCEPTION_VECTORS 17 #define MMIO_DEVID_EXCEPTION_VECTORS 17
#define MMIO_DEVID_MC0 18 #define MMIO_DEVID_AMS_IRAM_PAGE 18
#define MMIO_DEVID_MC1 19 #define MMIO_DEVID_AMS_USER_PAGE 19
#define MMIO_DEVID_AMS_IRAM_PAGE 20 #define MMIO_DEVID_DEBUG_IRAM 20
#define MMIO_DEVID_AMS_USER_PAGE 21 #define MMIO_DEVID_MAX 21
#define MMIO_DEVID_DEBUG_IRAM 22
#define MMIO_DEVID_MAX 23
#define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0 #define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1 #define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1

View File

@@ -149,7 +149,6 @@ static void setup_se(void) {
case ATMOSPHERE_TARGET_FIRMWARE_810: case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900: case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY); derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
break; break;
} }
@@ -339,7 +338,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
/* Perform version checks. */ /* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */ /* 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_1000_CURRENT) { if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_910_CURRENT) {
return true; return true;
} }
@@ -467,7 +466,6 @@ static void copy_warmboot_bin_to_dram() {
case ATMOSPHERE_TARGET_FIRMWARE_810: case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900: case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
warmboot_src = (uint8_t *)0x4003E000; warmboot_src = (uint8_t *)0x4003E000;
break; break;
} }
@@ -553,9 +551,6 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
MAKE_REG32(PMC_BASE + 0x360) = 0x18C; MAKE_REG32(PMC_BASE + 0x360) = 0x18C;
break; break;
case ATMOSPHERE_TARGET_FIRMWARE_1000:
MAKE_REG32(PMC_BASE + 0x360) = 0x1AD;
break;
} }
} }

View File

@@ -73,8 +73,7 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
#define PACKAGE2_MAXVER_700_800 0xA #define PACKAGE2_MAXVER_700_800 0xA
#define PACKAGE2_MAXVER_810 0xB #define PACKAGE2_MAXVER_810 0xB
#define PACKAGE2_MAXVER_900 0xC #define PACKAGE2_MAXVER_900 0xC
#define PACKAGE2_MAXVER_910_920 0xD #define PACKAGE2_MAXVER_910_CURRENT 0xD
#define PACKAGE2_MAXVER_1000_CURRENT 0xE
#define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_200 0x4
@@ -87,8 +86,7 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
#define PACKAGE2_MINVER_700_800 0xB #define PACKAGE2_MINVER_700_800 0xB
#define PACKAGE2_MINVER_810 0xC #define PACKAGE2_MINVER_810 0xC
#define PACKAGE2_MINVER_900 0xD #define PACKAGE2_MINVER_900 0xD
#define PACKAGE2_MINVER_910_920 0xE #define PACKAGE2_MINVER_910_CURRENT 0xE
#define PACKAGE2_MINVER_1000_CURRENT 0xF
typedef struct { typedef struct {
union { union {

View File

@@ -1,20 +0,0 @@
/*
* 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/>.
*/
#include "rsa_common.h"
/* Instantiate the shared RSA data inside a single translation unit. */
rsa_shared_data_t g_rsa_shared_data = {};

View File

@@ -1,36 +0,0 @@
/*
* 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/>.
*/
#ifndef EXOSPHERE_RSA_COMMON_H
#define EXOSPHERE_RSA_COMMON_H
#include <stdint.h>
typedef union {
struct {
uint8_t user_data[0x100];
} storage_exp_mod;
struct {
uint32_t master_key_rev;
uint32_t type;
uint64_t expected_label_hash[4];
} unwrap_titlekey;
} rsa_shared_data_t __attribute__((aligned(4)));
_Static_assert(sizeof(rsa_shared_data_t) == 0x100);
extern rsa_shared_data_t g_rsa_shared_data;
#endif

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include "utils.h" #include "utils.h"
@@ -47,25 +47,24 @@ void ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
ll->addr_info.address = 0; ll->addr_info.address = 0;
ll->addr_info.size = 0; ll->addr_info.size = 0;
} }
flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll)); flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll));
} }
void set_security_engine_callback(unsigned int (*callback)(void)) { void set_security_engine_callback(unsigned int (*callback)(void)) {
/* Set the callback. */ if (callback == NULL || g_se_callback != NULL) {
g_se_callback = callback; generic_panic();
}
/* Enable SE Interrupt firing for async op. */ g_se_callback = callback;
se_get_regs()->SE_INT_ENABLE = 0x10;
} }
/* Fires on Security Engine operation completion. */ /* Fires on Security Engine operation completion. */
void se_operation_completed(void) { void se_operation_completed(void) {
se_get_regs()->SE_INT_ENABLE = 0; se_get_regs()->SE_INT_ENABLE = 0;
unsigned int (*callback)(void) = g_se_callback; if (g_se_callback != NULL) {
if (callback != NULL) { g_se_callback();
g_se_callback = NULL; g_se_callback = NULL;
callback();
} }
} }
@@ -104,7 +103,7 @@ void se_validate_stored_vector(void) {
uint8_t calc_vector[0x10]; uint8_t calc_vector[0x10];
se_generate_test_vector(calc_vector); se_generate_test_vector(calc_vector);
/* Ensure nobody's messed with the security engine while we slept. */ /* Ensure nobody's messed with the security engine while we slept. */
if (memcmp(calc_vector, g_se_stored_test_vector, 0x10) != 0) { if (memcmp(calc_vector, g_se_stored_test_vector, 0x10) != 0) {
generic_panic(); generic_panic();
@@ -123,7 +122,7 @@ void se_generate_stored_vector(void) {
/* Set the flags for an AES keyslot. */ /* Set the flags for an AES keyslot. */
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -142,7 +141,7 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
/* Set the flags for an RSA keyslot. */ /* Set the flags for an RSA keyslot. */
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX) { if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic(); generic_panic();
} }
@@ -161,7 +160,7 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
void clear_aes_keyslot(unsigned int keyslot) { void clear_aes_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -175,7 +174,7 @@ void clear_aes_keyslot(unsigned int keyslot) {
void clear_rsa_keyslot(unsigned int keyslot) { void clear_rsa_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX) { if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic(); generic_panic();
} }
@@ -195,7 +194,7 @@ void clear_rsa_keyslot(unsigned int keyslot) {
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -208,7 +207,7 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) { void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) { if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
generic_panic(); generic_panic();
} }
@@ -229,7 +228,7 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) { if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
generic_panic(); generic_panic();
} }
@@ -242,7 +241,7 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
void clear_aes_keyslot_iv(unsigned int keyslot) { void clear_aes_keyslot_iv(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -261,7 +260,7 @@ void set_se_ctr(const void *ctr) {
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) { void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) { if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -277,7 +276,7 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) { void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -305,6 +304,9 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
/* Set the callback, for after the async operation. */ /* Set the callback, for after the async operation. */
set_security_engine_callback(callback); set_security_engine_callback(callback);
/* Enable SE Interrupt firing for async op. */
se->SE_INT_ENABLE = 0x10;
/* Setup Input/Output lists */ /* Setup Input/Output lists */
se->SE_IN_LL_ADDR = in_ll_paddr; se->SE_IN_LL_ADDR = in_ll_paddr;
se->SE_OUT_LL_ADDR = out_ll_paddr; se->SE_OUT_LL_ADDR = out_ll_paddr;
@@ -336,7 +338,7 @@ void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, ui
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback); se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback);
} }
void se_exp_mod(unsigned int keyslot, const void *buf, size_t size, unsigned int (*callback)(void)) { void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
uint8_t stack_buf[KEYSIZE_RSA_MAX]; uint8_t stack_buf[KEYSIZE_RSA_MAX];
@@ -346,7 +348,7 @@ void se_exp_mod(unsigned int keyslot, const void *buf, size_t size, unsigned int
/* Endian swap the input. */ /* Endian swap the input. */
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
stack_buf[i] = *((const uint8_t *)buf + size - i - 1); stack_buf[i] = *((uint8_t *)buf + size - i - 1);
} }
se->SE_CONFIG = (ALG_RSA | DST_RSAREG); se->SE_CONFIG = (ALG_RSA | DST_RSAREG);
@@ -356,6 +358,9 @@ void se_exp_mod(unsigned int keyslot, const void *buf, size_t size, unsigned int
set_security_engine_callback(callback); set_security_engine_callback(callback);
/* Enable SE interrupt firing for async op. */
se->SE_INT_ENABLE = 0x10;
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX); flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
trigger_se_rsa_op(stack_buf, size); trigger_se_rsa_op(stack_buf, size);
@@ -463,7 +468,7 @@ bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const v
void trigger_se_rsa_op(void *buf, size_t size) { void trigger_se_rsa_op(void *buf, size_t size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
se_ll_t in_ll; se_ll_t in_ll;
ll_init(&in_ll, (void *)buf, size); ll_init(&in_ll, (void *)buf, size);
/* Set the input LL. */ /* Set the input LL. */
@@ -486,19 +491,19 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
ll_init(&in_ll, (void *)src, src_size); ll_init(&in_ll, (void *)src, src_size);
ll_init(&out_ll, dst, dst_size); ll_init(&out_ll, dst, dst_size);
__dsb_sy(); __dsb_sy();
/* Set the LLs. */ /* Set the LLs. */
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll);
/* Set registers for operation. */ /* Set registers for operation. */
se->SE_ERR_STATUS = se->SE_ERR_STATUS; se->SE_ERR_STATUS = se->SE_ERR_STATUS;
se->SE_INT_STATUS = se->SE_INT_STATUS; se->SE_INT_STATUS = se->SE_INT_STATUS;
se->SE_OPERATION = op; se->SE_OPERATION = op;
(void)(se->SE_OPERATION); (void)(se->SE_OPERATION);
__dsb_ish(); __dsb_ish();
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
@@ -533,7 +538,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) { void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) { if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
generic_panic(); generic_panic();
} }
@@ -543,7 +548,7 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
} }
if (dst_size) { if (dst_size) {
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size); flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size);
} }
unsigned int num_blocks = src_size >> 4; unsigned int num_blocks = src_size >> 4;
@@ -571,12 +576,12 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
if (dst_size) { if (dst_size) {
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size); flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size);
} }
} }
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) { void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic(); generic_panic();
} }
@@ -601,7 +606,7 @@ void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic(); generic_panic();
} }
@@ -627,15 +632,15 @@ void shift_left_xor_rb(uint8_t *key) {
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) { void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
if (data_size) { if (data_size) {
flush_dcache_range((uint8_t *)data, (uint8_t *)data + data_size); flush_dcache_range((uint8_t *)data, (uint8_t *)data + data_size);
} }
/* Generate the derived key, to be XOR'd with final output block. */ /* Generate the derived key, to be XOR'd with final output block. */
uint8_t derived_key[0x10] = {0}; uint8_t derived_key[0x10] = {0};
se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high); se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
@@ -647,7 +652,7 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
clear_aes_keyslot_iv(keyslot); clear_aes_keyslot_iv(keyslot);
unsigned int num_blocks = (data_size + 0xF) >> 4; unsigned int num_blocks = (data_size + 0xF) >> 4;
/* Handle aligned blocks. */ /* Handle aligned blocks. */
if (num_blocks > 1) { if (num_blocks > 1) {
@@ -655,7 +660,7 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
se->SE_CRYPTO_CONFIG |= 0x80; se->SE_CRYPTO_CONFIG |= 0x80;
} }
/* Create final block. */ /* Create final block. */
uint8_t last_block[0x10] = {0}; uint8_t last_block[0x10] = {0};
if (data_size & 0xF) { if (data_size & 0xF) {
@@ -664,11 +669,11 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
} else if (data_size >= 0x10) { } else if (data_size >= 0x10) {
memcpy(last_block, data + data_size - 0x10, 0x10); memcpy(last_block, data + data_size - 0x10, 0x10);
} }
for (unsigned int i = 0; i < 0x10; i++) { for (unsigned int i = 0; i < 0x10; i++) {
last_block[i] ^= derived_key[i]; last_block[i] ^= derived_key[i];
} }
/* Perform last operation. */ /* Perform last operation. */
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
flush_dcache_range(last_block, last_block + sizeof(last_block)); flush_dcache_range(last_block, last_block + sizeof(last_block));
@@ -689,11 +694,11 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size,
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) { void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) { if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
generic_panic(); generic_panic();
} }
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144;
set_aes_keyslot_iv(keyslot, iv, 0x10); set_aes_keyslot_iv(keyslot, iv, 0x10);
@@ -704,7 +709,7 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co
/* SHA256 Implementation. */ /* SHA256 Implementation. */
void se_calculate_sha256(void *dst, const void *src, size_t src_size) { void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
/* Setup config for SHA256, size = BITS(src_size) */ /* Setup config for SHA256, size = BITS(src_size) */
se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
se->SE_SHA_CONFIG = 1; se->SE_SHA_CONFIG = 1;
@@ -716,7 +721,7 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
se->SE_SHA_MSG_LEFT[1] = 0; se->SE_SHA_MSG_LEFT[1] = 0;
se->SE_SHA_MSG_LEFT[2] = 0; se->SE_SHA_MSG_LEFT[2] = 0;
se->SE_SHA_MSG_LEFT[3] = 0; se->SE_SHA_MSG_LEFT[3] = 0;
/* Trigger the operation. */ /* Trigger the operation. */
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
@@ -729,7 +734,7 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
/* RNG API */ /* RNG API */
void se_initialize_rng(unsigned int keyslot) { void se_initialize_rng(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -749,7 +754,7 @@ void se_initialize_rng(unsigned int keyslot) {
void se_generate_random(unsigned int keyslot, void *dst, size_t size) { void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) { if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -772,7 +777,7 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
/* SE context save API. */ /* SE context save API. */
void se_set_in_context_save_mode(bool is_context_save_mode) { void se_set_in_context_save_mode(bool is_context_save_mode) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
uint32_t val = se->SE_SE_SECURITY; uint32_t val = se->SE_SE_SECURITY;
if (is_context_save_mode) { if (is_context_save_mode) {
val |= 0x10000; val |= 0x10000;
@@ -786,7 +791,7 @@ void se_set_in_context_save_mode(bool is_context_save_mode) {
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) { void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) { if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) {
generic_panic(); generic_panic();
} }
@@ -796,7 +801,7 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot)
se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108; se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108;
se->SE_RNG_CONFIG = 4; se->SE_RNG_CONFIG = 4;
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
/* Generate low part of key. */ /* Generate low part of key. */
se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8); se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8);
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
@@ -807,7 +812,7 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot)
void se_generate_srk(unsigned int srkgen_keyslot) { void se_generate_srk(unsigned int srkgen_keyslot) {
volatile tegra_se_t *se = se_get_regs(); volatile tegra_se_t *se = se_get_regs();
se->SE_CONFIG = (ALG_RNG | DST_SRK); se->SE_CONFIG = (ALG_RNG | DST_SRK);
se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108; se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108;
se->SE_RNG_CONFIG = 6; se->SE_RNG_CONFIG = 6;
@@ -842,24 +847,24 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
/* Generate the SRK (context save encryption key). */ /* Generate the SRK (context save encryption key). */
se_generate_random_key(srkgen_keyslot, rng_keyslot); se_generate_random_key(srkgen_keyslot, rng_keyslot);
se_generate_srk(srkgen_keyslot); se_generate_srk(srkgen_keyslot);
flush_dcache_range(work_buf, work_buf + 0x10); flush_dcache_range(work_buf, work_buf + 0x10);
se_generate_random(rng_keyslot, work_buf, 0x10); se_generate_random(rng_keyslot, work_buf, 0x10);
flush_dcache_range(work_buf, work_buf + 0x10); flush_dcache_range(work_buf, work_buf + 0x10);
/* Save random initial block. */ /* Save random initial block. */
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst, 0x10, work_buf, 0x10); se_encrypt_with_srk(dst, 0x10, work_buf, 0x10);
/* Save Sticky Bits. */ /* Save Sticky Bits. */
for (unsigned int i = 0; i < 0x2; i++) { for (unsigned int i = 0; i < 0x2; i++) {
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0); se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0);
} }
/* Save AES Key Table. */ /* Save AES Key Table. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
@@ -869,21 +874,21 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0); se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0);
} }
/* Save AES Original IVs. */ /* Save AES Original IVs. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0); se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0);
} }
/* Save AES Updated IVs */ /* Save AES Updated IVs */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0); se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0);
} }
/* Save RSA Keytable. */ /* Save RSA Keytable. */
uint8_t *rsa_ctx_out = (uint8_t *)dst + 0x430; uint8_t *rsa_ctx_out = (uint8_t *)dst + 0x430;
for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) { for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) {
@@ -896,13 +901,13 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
} }
} }
} }
/* Save "Known Pattern. " */ /* Save "Known Pattern. " */
static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;
se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10); se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10);
/* Save SRK into PMC registers. */ /* Save SRK into PMC registers. */
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK); se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK);
se->SE_CRYPTO_LAST_BLOCK = 0; se->SE_CRYPTO_LAST_BLOCK = 0;

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EXOSPHERE_SE_H #ifndef EXOSPHERE_SE_H
#define EXOSPHERE_SE_H #define EXOSPHERE_SE_H
@@ -213,7 +213,7 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co
void se_calculate_sha256(void *dst, const void *src, size_t src_size); void se_calculate_sha256(void *dst, const void *src, size_t src_size);
/* RSA API */ /* RSA API */
void se_exp_mod(unsigned int keyslot, const void *buf, size_t size, unsigned int (*callback)(void)); void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void));
void se_get_exp_mod_output(void *buf, size_t size); void se_get_exp_mod_output(void *buf, size_t size);
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size); bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size);

View File

@@ -25,8 +25,6 @@
#include "synchronization.h" #include "synchronization.h"
#include "masterkey.h" #include "masterkey.h"
#include "mc.h" #include "mc.h"
#include "mc0.h"
#include "mc1.h"
#include "memory_map.h" #include "memory_map.h"
#include "pmc.h" #include "pmc.h"
#include "randomcache.h" #include "randomcache.h"
@@ -190,7 +188,6 @@ void set_version_specific_smcs(void) {
case ATMOSPHERE_TARGET_FIRMWARE_810: case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900: case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
/* No more LoadSecureExpModKey. */ /* No more LoadSecureExpModKey. */
g_smc_user_table[0xE].handler = NULL; g_smc_user_table[0xE].handler = NULL;
g_smc_user_table[0xC].id = 0xC300D60C; g_smc_user_table[0xC].id = 0xC300D60C;
@@ -436,18 +433,19 @@ uint32_t smc_get_result(smc_args_t *args) {
} }
uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) { uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) {
uint32_t res = get_exp_mod_result(); if (get_exp_mod_done() != 1) {
if (res == 0) { return 3;
if (size == 0x100) {
se_get_exp_mod_output(buf, 0x100);
/* smc_exp_mod is done now. */
clear_user_smc_in_progress();
res = 0;
} else {
res = 2;
}
} }
return res;
if (size != 0x100) {
return 2;
}
se_get_exp_mod_output(buf, 0x100);
/* smc_exp_mod is done now. */
clear_user_smc_in_progress();
return 0;
} }
uint32_t smc_exp_mod(smc_args_t *args) { uint32_t smc_exp_mod(smc_args_t *args) {
@@ -510,31 +508,30 @@ uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey_get_result(void *buf, uint64_t siz
uint8_t aes_wrapped_titlekey[0x10]; uint8_t aes_wrapped_titlekey[0x10];
uint8_t titlekey[0x10]; uint8_t titlekey[0x10];
uint64_t sealed_titlekey[2]; uint64_t sealed_titlekey[2];
uint32_t res = get_exp_mod_result(); if (get_exp_mod_done() != 1) {
if (res == 0) { return 3;
if (size == 0x10) {
se_get_exp_mod_output(rsa_wrapped_titlekey, 0x100);
if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) == 0x10) {
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
p_sealed_key[0] = sealed_titlekey[0];
p_sealed_key[1] = sealed_titlekey[1];
res = 0;
} else {
/* Failed to extract RSA OAEP wrapped key. */
res = 2;
}
/* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */
clear_user_smc_in_progress();
} else {
res = 2;
}
} }
return res; if (size != 0x10) {
return 2;
}
se_get_exp_mod_output(rsa_wrapped_titlekey, 0x100);
if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) {
/* Failed to extract RSA OAEP wrapped key. */
clear_user_smc_in_progress();
return 2;
}
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
p_sealed_key[0] = sealed_titlekey[0];
p_sealed_key[1] = sealed_titlekey[1];
/* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */
clear_user_smc_in_progress();
return 0;
} }
uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) { uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
@@ -619,7 +616,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
} }
/* Check for PMC registers. */ /* Check for PMC registers. */
if (0x7000E400 <= address && address <= 0x7000EFFF) { if (0x7000E400 <= address && address <= 0x7000EFFF) {
static const uint8_t pmc_whitelist[0x28] = { const uint8_t pmc_whitelist[0x28] = {
0xB9, 0xF9, 0x07, 0x00, 0x00, 0x00, 0x80, 0x03, 0xB9, 0xF9, 0x07, 0x00, 0x00, 0x00, 0x80, 0x03,
0x00, 0x00, 0x00, 0x17, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0xC4, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00,
@@ -635,83 +632,39 @@ uint32_t smc_read_write_register(smc_args_t *args) {
} else { } else {
return 2; return 2;
} }
} else { } else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) { address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + MMIO_GET_DEVICE_SIZE(MMIO_DEVID_MC)) {
static const uint8_t mc_whitelist_5x[0xD00/(sizeof(uint32_t) * 8)] = { /* Memory Controller RW supported only on 4.0.0+ */
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01, const uint8_t mc_whitelist[0x68] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E, 0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04, 0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
0x80, 0xFF, 0x08, 0x80, 0x03, 0x38, 0x8E, 0x1F, 0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04,
0xC8, 0xFF, 0xFF, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x08, 0x80, 0x03, 0x00, 0x0E, 0x00,
0xF0, 0x1F, 0x00, 0x30, 0xF0, 0x03, 0x03, 0x30, 0x08, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xF0, 0x03, 0x03, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xE4, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x03, 0x00, 0x00, 0xE4, 0xFF, 0xFF, 0x01,
0x01, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0F,
}; 0x01, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00
static const uint8_t mc01_whitelist_5x[0xC00/(sizeof(uint32_t) * 8)] = { };
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, uint32_t offset = (uint32_t)(address - 0x70019000);
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, uint32_t wl_ind = (offset >> 5);
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* If address is whitelisted, allow write. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, if (wl_ind < sizeof(mc_whitelist) && (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, p_mmio = (volatile uint32_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC) + offset);
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } else {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* These addresses are not allowed by the whitelist. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* They correspond to SMMU DISABLE for the BPMP, and for APB-DMA. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* However, smcReadWriteRegister returns 0 for these addresses despite not actually performing the write. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* This is "probably" to fuck with hackers who got access to smcReadWriteRegister and are trying to get */
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* control of the BPMP for jamais vu etc., since there's no other reason to return 0 despite failure. */
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, if (address == 0x7001923C || address == 0x70019298) {
}; return 0;
static const struct {
uint32_t phys_addr;
uint32_t size;
uint64_t virt_addr;
const uint8_t *whitelist;
} register_whitelists[3] = {
{ MMIO_GET_DEVICE_PA(MMIO_DEVID_MC), sizeof(mc_whitelist_5x) * (sizeof(uint32_t) * 8), MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC), mc_whitelist_5x },
{ MMIO_GET_DEVICE_PA(MMIO_DEVID_MC0), sizeof(mc01_whitelist_5x) * (sizeof(uint32_t) * 8), MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC0), mc01_whitelist_5x },
{ MMIO_GET_DEVICE_PA(MMIO_DEVID_MC1), sizeof(mc01_whitelist_5x) * (sizeof(uint32_t) * 8), MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC1), mc01_whitelist_5x },
};
for (unsigned int which = 0; which < 3; which++) {
if (register_whitelists[which].phys_addr <= address && address < register_whitelists[which].phys_addr + register_whitelists[which].size) {
uint32_t offset = (uint32_t)(address - register_whitelists[which].phys_addr);
uint32_t wl_ind = (offset >> 5);
/* If address is whitelisted, allow write. */
if (register_whitelists[which].whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7))) {
p_mmio = (volatile uint32_t *)(register_whitelists[which].virt_addr + offset);
}
break;
}
}
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address && address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + 0xD00) {
/* Memory Controller RW supported only on 4.0.0+ */
static const uint8_t mc_whitelist[0x68] = {
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04,
0x80, 0x1F, 0x08, 0x80, 0x03, 0x00, 0x0E, 0x00,
0x08, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0xF0, 0x03, 0x03, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0xE4, 0xFF, 0xFF, 0x01,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0F,
0x01, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00
};
uint32_t offset = (uint32_t)(address - MMIO_GET_DEVICE_PA(MMIO_DEVID_MC));
uint32_t wl_ind = (offset >> 5);
/* If address is whitelisted, allow write. */
if (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7))) {
p_mmio = (volatile uint32_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC) + offset);
}
} }
return 2;
} }
} }
@@ -730,16 +683,9 @@ uint32_t smc_read_write_register(smc_args_t *args) {
/* Return old value. */ /* Return old value. */
args->X[1] = old_value; args->X[1] = old_value;
return 0; return 0;
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && (address == 0x7001923C || address == 0x70019298)) {
/* These addresses are not allowed by the whitelist. */
/* They correspond to SMMU DISABLE for the BPMP, and for APB-DMA. */
/* However, smcReadWriteRegister returns 0 for these addresses despite not actually performing the write. */
/* This is "probably" to fuck with hackers who got access to smcReadWriteRegister and are trying to get */
/* control of the BPMP for jamais vu etc., since there's no other reason to return 0 despite failure. */
return 0;
} else {
return 2;
} }
return 2;
} }

View File

@@ -34,93 +34,12 @@
/* Globals. */ /* Globals. */
static bool g_crypt_aes_done = false; static bool g_crypt_aes_done = false;
static uint32_t g_exp_mod_result = 0; static bool g_exp_mod_done = false;
static __attribute__((aligned(4))) uint8_t g_imported_exponents[4][0x100]; static uint8_t g_imported_exponents[4][0x100];
static __attribute__((aligned(4))) uint8_t g_imported_moduli[4][0x100];
static bool g_is_modulus_verified[4];
static __attribute__((aligned(4))) const uint8_t g_rsa_public_key[4] = { 0x00, 0x01, 0x00, 0x01 };
static __attribute__((aligned(4))) const uint8_t g_rsa_test_vector[0x100] = {
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D'
};
static uint32_t g_test_exp_mod_keyslot = 0;
static uint32_t g_test_exp_mod_usecase = 0;
static bool g_test_exp_mod_in_progress = false;
static uint8_t g_rsausecase_to_cryptousecase[5] = {1, 2, 3, 5, 6}; static uint8_t g_rsausecase_to_cryptousecase[5] = {1, 2, 3, 5, 6};
static void import_rsa_exponent(unsigned int which, const uint8_t *exponent, uint64_t size) {
g_is_modulus_verified[which] = false;
for (unsigned int i = 0; i < 0x100; i++) {
g_imported_exponents[which][i] = exponent[i];
g_imported_moduli[which][i] = 0;
}
}
static void import_rsa_modulus(unsigned int which, const uint8_t *modulus, uint64_t size) {
uint64_t clamped_size = 0x100;
if (size <= 0x100) {
clamped_size = size;
}
if (clamped_size != 0) {
/* The official secure monitor implements this via bit-fiddling, */
/* and to prevent accidental inaccuracy we will too. */
/* It's probably done to prevent errors on negative sizes. */
uint64_t remaining = 0x100;
if (size != 0x100 && (~size >= ~0xFFFFFFFFFFFFFEFFULL)) {
remaining = size;
}
memcpy(&g_imported_moduli[which][0], modulus, remaining);
}
}
static bool load_imported_rsa_keypair(unsigned int keyslot, unsigned int which) {
if (!g_is_modulus_verified[which]) {
return false;
}
set_rsa_keyslot(keyslot, g_imported_moduli[which], 0x100, g_imported_exponents[which], 0x100);
return true;
}
static void test_rsa_modulus_public(unsigned int which, unsigned int keyslot, const uint8_t *modulus, uint64_t modulus_size, unsigned int (*callback)(void)) {
import_rsa_modulus(which, modulus, modulus_size);
set_rsa_keyslot(keyslot, modulus, modulus_size, g_rsa_public_key, 0x4);
se_exp_mod(keyslot, g_rsa_test_vector, 0x100, callback);
}
static void test_rsa_modulus_private(unsigned int which, unsigned int keyslot, unsigned int (*callback)(void)) {
uint8_t exponentiated_data[0x100];
se_get_exp_mod_output(exponentiated_data, sizeof(exponentiated_data));
set_rsa_keyslot(keyslot, g_imported_moduli[which], 0x100, g_imported_exponents[which], 0x100);
se_exp_mod(keyslot, exponentiated_data, 0x100, callback);
}
static void validate_rsa_result(unsigned int which) {
char result[0x100];
se_get_exp_mod_output(result, sizeof(result));
if (memcmp(result, g_rsa_test_vector, sizeof(result)) == 0) {
g_is_modulus_verified[which] = true;
}
}
static bool is_user_keyslot_valid(unsigned int keyslot) { static bool is_user_keyslot_valid(unsigned int keyslot) {
switch (exosphere_get_target_firmware()) { switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100: case ATMOSPHERE_TARGET_FIRMWARE_100:
@@ -136,45 +55,27 @@ static bool is_user_keyslot_valid(unsigned int keyslot) {
case ATMOSPHERE_TARGET_FIRMWARE_810: case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900: case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
default: default:
return keyslot <= 5; return keyslot <= 5;
} }
} }
void set_exp_mod_result(uint32_t result) { void set_exp_mod_done(bool done) {
g_exp_mod_result = result; g_exp_mod_done = done;
} }
uint32_t get_exp_mod_result(void) { bool get_exp_mod_done(void) {
return g_exp_mod_result; return g_exp_mod_done;
} }
uint32_t exp_mod_done_handler(void) { uint32_t exp_mod_done_handler(void) {
set_exp_mod_result(0); set_exp_mod_done(true);
se_trigger_interrupt(); se_trigger_interrupt();
return 0; return 0;
} }
static uint32_t test_exp_mod_done_handler(void) {
if (g_test_exp_mod_in_progress) {
g_test_exp_mod_in_progress = false;
test_rsa_modulus_private(g_test_exp_mod_usecase, g_test_exp_mod_keyslot, test_exp_mod_done_handler);
} else {
validate_rsa_result(g_test_exp_mod_usecase);
if (load_imported_rsa_keypair(g_test_exp_mod_keyslot, g_test_exp_mod_usecase)) {
se_exp_mod(g_test_exp_mod_keyslot, g_rsa_shared_data.storage_exp_mod.user_data, 0x100, exp_mod_done_handler);
} else {
set_exp_mod_result(2);
se_trigger_interrupt();
}
}
return 0;
}
uint32_t user_exp_mod(smc_args_t *args) { uint32_t user_exp_mod(smc_args_t *args) {
uint8_t modulus[0x100]; uint8_t modulus[0x100];
uint8_t exponent[0x100]; uint8_t exponent[0x100];
@@ -207,8 +108,7 @@ uint32_t user_exp_mod(smc_args_t *args) {
return 2; return 2;
} }
set_exp_mod_result(3); set_exp_mod_done(false);
/* Hardcode RSA keyslot 0. */ /* Hardcode RSA keyslot 0. */
set_rsa_keyslot(0, modulus, 0x100, exponent, exponent_size); set_rsa_keyslot(0, modulus, 0x100, exponent, exponent_size);
se_exp_mod(0, input, 0x100, exp_mod_done_handler); se_exp_mod(0, input, 0x100, exp_mod_done_handler);
@@ -750,21 +650,10 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
return 2; return 2;
} }
set_exp_mod_result(3); set_exp_mod_done(false);
/* Hardcode RSA keyslot 0. */ /* Hardcode RSA keyslot 0. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_1000) { set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[exponent_id], 0x100);
set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[exponent_id], 0x100); se_exp_mod(0, input, 0x100, exp_mod_done_handler);
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
} else if (load_imported_rsa_keypair(0, exponent_id)) {
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
} else {
memcpy(g_rsa_shared_data.storage_exp_mod.user_data, input, 0x100);
g_test_exp_mod_keyslot = 0;
g_test_exp_mod_usecase = exponent_id;
g_test_exp_mod_in_progress = true;
test_rsa_modulus_public(exponent_id, 0, modulus, 0x100, test_exp_mod_done_handler);
}
return 0; return 0;
} }
@@ -811,7 +700,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
return 2; return 2;
} }
set_exp_mod_result(3); set_exp_mod_done(false);
/* Expected label_hash occupies args->X[3] to args->X[6]. */ /* Expected label_hash occupies args->X[3] to args->X[6]. */
tkey_set_expected_label_hash(&args->X[3]); tkey_set_expected_label_hash(&args->X[3]);
@@ -990,7 +879,6 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
} }
unsigned int exponent_id; unsigned int exponent_id;
bool import_modulus;
switch (usecase) { switch (usecase) {
case 0: case 0:
@@ -1000,33 +888,22 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
return 0; return 0;
case 1: case 1:
exponent_id = 1; exponent_id = 1;
import_modulus = false;
break; break;
case 2: case 2:
exponent_id = 0; exponent_id = 0;
import_modulus = true;
break; break;
case 3: case 3:
exponent_id = 2; exponent_id = 2;
import_modulus = false;
break; break;
case 4: case 4:
exponent_id = 3; exponent_id = 3;
import_modulus = true;
break; break;
default: default:
generic_panic(); generic_panic();
} }
/* Modulus import isn't implemented on < 10.0.0. */ /* Copy key to global. */
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_1000); memcpy(g_imported_exponents[exponent_id], user_data, 0x100);
/* Import the key. */
import_rsa_exponent(exponent_id, user_data, 0x100);
if (import_modulus) {
import_rsa_modulus(exponent_id, user_data + 0x100, 0x100);
g_is_modulus_verified[exponent_id] = true;
}
return 0; return 0;
} }

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EXOSPHERE_SMC_USER_H #ifndef EXOSPHERE_SMC_USER_H
#define EXOSPHERE_SMC_USER_H #define EXOSPHERE_SMC_USER_H
@@ -41,7 +41,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args);
void set_crypt_aes_done(bool done); void set_crypt_aes_done(bool done);
bool get_crypt_aes_done(void); bool get_crypt_aes_done(void);
void set_exp_mod_result(uint32_t result); void set_exp_mod_done(bool done);
uint32_t get_exp_mod_result(void); bool get_exp_mod_done(void);
#endif #endif

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -25,10 +25,14 @@
#include "masterkey.h" #include "masterkey.h"
#include "se.h" #include "se.h"
static uint64_t g_tkey_expected_label_hash[4];
static unsigned int g_tkey_master_key_rev = MASTERKEY_REVISION_MAX;
static unsigned int g_tkey_type = 0;
/* Set the expected db prefix. */ /* Set the expected db prefix. */
void tkey_set_expected_label_hash(uint64_t *label_hash) { void tkey_set_expected_label_hash(uint64_t *label_hash) {
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
g_rsa_shared_data.unwrap_titlekey.expected_label_hash[i] = label_hash[i]; g_tkey_expected_label_hash[i] = label_hash[i];
} }
} }
@@ -36,7 +40,7 @@ void tkey_set_master_key_rev(unsigned int master_key_rev) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) { if (master_key_rev >= MASTERKEY_REVISION_MAX) {
generic_panic(); generic_panic();
} }
g_rsa_shared_data.unwrap_titlekey.master_key_rev = master_key_rev; g_tkey_master_key_rev = master_key_rev;
} }
static void tkey_validate_type(unsigned int type) { static void tkey_validate_type(unsigned int type) {
@@ -47,7 +51,7 @@ static void tkey_validate_type(unsigned int type) {
void tkey_set_type(unsigned int type) { void tkey_set_type(unsigned int type) {
tkey_validate_type(type); tkey_validate_type(type);
g_rsa_shared_data.unwrap_titlekey.type = type; g_tkey_type = type;
} }
/* Reference for MGF1 can be found here: https://en.wikipedia.org/wiki/Mask_generation_function#MGF1 */ /* Reference for MGF1 can be found here: https://en.wikipedia.org/wiki/Mask_generation_function#MGF1 */
@@ -112,7 +116,7 @@ size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_si
uint8_t *db = message + 0x21; uint8_t *db = message + 0x21;
/* This will be passed to smc_unwrap_rsa_oaep_wrapped_titlekey. */ /* This will be passed to smc_unwrap_rsa_oaep_wrapped_titlekey. */
uint8_t *expected_label_hash = (uint8_t *)(&g_rsa_shared_data.unwrap_titlekey.expected_label_hash[0]); uint8_t *expected_label_hash = (uint8_t *)(&g_tkey_expected_label_hash[0]);
/* Unmask the salt. */ /* Unmask the salt. */
calculate_mgf1_and_xor(salt, 0x20, db, 0xDF); calculate_mgf1_and_xor(salt, 0x20, db, 0xDF);
@@ -167,13 +171,13 @@ static const uint8_t titlekek_sources[TITLEKEY_TYPE_MAX+1][0x10] = {
}; };
void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size) { void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size) {
if (g_rsa_shared_data.unwrap_titlekey.master_key_rev >= MASTERKEY_REVISION_MAX || dst_size != 0x10 || src_size != 0x10) { if (g_tkey_master_key_rev >= MASTERKEY_REVISION_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic(); generic_panic();
} }
/* Generate the appropriate titlekek into keyslot 9. */ /* Generate the appropriate titlekek into keyslot 9. */
unsigned int master_keyslot = mkey_get_keyslot(g_rsa_shared_data.unwrap_titlekey.master_key_rev); unsigned int master_keyslot = mkey_get_keyslot(g_tkey_master_key_rev);
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_sources[g_rsa_shared_data.unwrap_titlekey.type], 0x10); decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_sources[g_tkey_type], 0x10);
/* Unwrap the titlekey using the titlekek. */ /* Unwrap the titlekey using the titlekek. */
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, dst, 0x10, src, 0x10); se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, dst, 0x10, src, 0x10);

View File

@@ -13,12 +13,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EXOSPHERE_TITLEKEY_H #ifndef EXOSPHERE_TITLEKEY_H
#define EXOSPHERE_TITLEKEY_H #define EXOSPHERE_TITLEKEY_H
#include <stdint.h> #include <stdint.h>
#include "rsa_common.h"
#define TITLEKEY_TYPE_MAX 0x1 #define TITLEKEY_TYPE_MAX 0x1

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "utils.h" #include "utils.h"
#include "memory_map.h" #include "memory_map.h"
#include "mc.h" #include "mc.h"
@@ -65,7 +65,7 @@ void init_dma_controllers(unsigned int target_firmware) {
MAKE_REG32(0x6000C038) = 0x0; MAKE_REG32(0x6000C038) = 0x0;
/* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */ /* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */
MAKE_REG32(0x50060000) = (MAKE_REG32(0x50060000) & 0xC4FFFFFF) | 0x38000000; MAKE_REG32(0x50060000) |= 0x38000000;
/* AHB_ARBITRATION_DISABLE_0 - Disables USB, USB2, and AHB-DMA from arbitration */ /* AHB_ARBITRATION_DISABLE_0 - Disables USB, USB2, and AHB-DMA from arbitration */
MAKE_REG32(0x6000C004) = 0x40060; MAKE_REG32(0x6000C004) = 0x40060;
@@ -99,7 +99,7 @@ void init_dma_controllers(unsigned int target_firmware) {
MAKE_REG32(0x60020038) = 0; MAKE_REG32(0x60020038) = 0;
/* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */ /* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */
MAKE_REG32(0x50060000) |= (MAKE_REG32(0x50060000) & 0xC4FFFFFF) | 0x38000000; MAKE_REG32(0x50060000) |= 0x38000000;
/* AHB_ARBITRATION_PRIORITY_CTRL_0 - Select high prio group with prio 7 */ /* AHB_ARBITRATION_PRIORITY_CTRL_0 - Select high prio group with prio 7 */
MAKE_REG32(0x6000C008) = 0xE0000001; MAKE_REG32(0x6000C008) = 0xE0000001;
@@ -111,14 +111,6 @@ void init_dma_controllers(unsigned int target_firmware) {
void _set_memory_registers_enable_mmu(const uintptr_t ttbr0) { void _set_memory_registers_enable_mmu(const uintptr_t ttbr0) {
static const uintptr_t vbar = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800; static const uintptr_t vbar = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800;
/*
- Non-cacheable load forwarding enabled
- Disable load-pass DMB.
- NOTE: This and this alone is done via inline asm, due to register argument limits.
*/
static const uint64_t cpuactlr = 0x800000001000000ull;
__asm__ __volatile__("msr s3_1_c15_c2_0, %0" :: "r"(cpuactlr) : "memory", "cc");
/* /*
- Disable table walk descriptor access prefetch. - Disable table walk descriptor access prefetch.
@@ -205,12 +197,12 @@ void warmboot_init(void) {
*/ */
flush_dcache_all(); flush_dcache_all();
invalidate_icache_all(); invalidate_icache_all();
/* On warmboot (not cpu_on) only */ /* On warmboot (not cpu_on) only */
if (VIRT_MC_SECURITY_CFG3 == 0) { if (VIRT_MC_SECURITY_CFG3 == 0) {
init_dma_controllers(g_exosphere_target_firmware_for_init); init_dma_controllers(g_exosphere_target_firmware_for_init);
} }
/*identity_remap_tzram();*/ /*identity_remap_tzram();*/
/* Nintendo pointlessly fully invalidate the TLB & invalidate the data cache on the modified ranges here */ /* Nintendo pointlessly fully invalidate the TLB & invalidate the data cache on the modified ranges here */
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) { if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {

View File

@@ -82,9 +82,6 @@ typedef enum {
FS_VER_9_1_0, FS_VER_9_1_0,
FS_VER_9_1_0_EXFAT, FS_VER_9_1_0_EXFAT,
FS_VER_10_0_0,
FS_VER_10_0_0_EXFAT,
FS_VER_MAX, FS_VER_MAX,
} emummc_fs_ver_t; } emummc_fs_ver_t;

View File

@@ -417,9 +417,6 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", /* FS_VER_9_1_0 */ "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", /* FS_VER_9_1_0 */
"\xF1\x96\xD1\x44\xD0\x44\x45\xB6", /* FS_VER_9_1_0_EXFAT */ "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", /* FS_VER_9_1_0_EXFAT */
"\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", /* FS_VER_10_0_0 */
"\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", /* FS_VER_10_0_0_EXFAT */
}; };
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) { kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -486,77 +486,20 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(900, proc_id_send)[] = {0xA9BF
static const uint8_t MAKE_KERNEL_PATTERN_NAME(900, proc_id_recv)[] = {0x68, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1B, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x03, 0x17, 0x2A, 0xF7, 0x0A, 0x00, 0x11, 0x08, 0xF5, 0x7E, 0xD3}; static const uint8_t MAKE_KERNEL_PATTERN_NAME(900, proc_id_recv)[] = {0x68, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1B, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x03, 0x17, 0x2A, 0xF7, 0x0A, 0x00, 0x11, 0x08, 0xF5, 0x7E, 0xD3};
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, proc_id_recv)[] = {0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; static const instruction_t MAKE_KERNEL_PATCH_NAME(900, proc_id_recv)[] = {0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xC0]
mov w10, w22
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x23]
ldr x8, [x8, #0x38]
mov x0, x23
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_send)[] = {0xE8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x17, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0x08, 0x4B, 0x36, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_send)[] = {0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xC8]
mov w10, w26
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x28]
ldr x8, [x8, #0x38]
mov x0, x28
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x87, 0x40, 0xF9, 0x08, 0x49, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/* svcControlCodeMemory Patches */ /* svcControlCodeMemory Patches */
/* b.eq -> nop */ /* b.eq -> nop */
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(600, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(600, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(700, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(700, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(700, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(700, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
/* Hook Definitions. */ /* Hook Definitions. */
static const kernel_patch_t g_kernel_patches_100[] = { static const kernel_patch_t g_kernel_patches_100[] = {
@@ -792,35 +735,6 @@ static const kernel_patch_t g_kernel_patches_900[] = {
} }
}; };
static const kernel_patch_t g_kernel_patches_1000[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1000, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1000, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)
},
{ /* svcControlCodeMemory Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory),
.patch_offset = 0x45DAC,
},
{ /* System Memory Increase Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase),
.patch_offset = 0x66950,
}
};
#define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers, #define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers,
/* Kernel Infos. */ /* Kernel Infos. */
@@ -897,15 +811,6 @@ static const kernel_info_t g_kernel_infos[] = {
.embedded_ini_ptr = 0x180, .embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x65780, .free_code_space_offset = 0x65780,
KERNEL_PATCHES(900) KERNEL_PATCHES(900)
},
{ /* 10.0.0. */
.hash = {0x59, 0x31, 0xE6, 0x46, 0xF7, 0xAA, 0x15, 0x59, 0x78, 0xC7, 0xB3, 0xA5, 0xFA, 0x80, 0xE2, 0xC0, 0xCA, 0x6F, 0x31, 0x97, 0x3D, 0x86, 0x8A, 0x69, 0xF3, 0xBF, 0xE6, 0xE5, 0x61, 0xA7, 0x1B, 0x5B, },
.hash_offset = 0x1B8,
.hash_size = 0x93000 - 0x1B8,
.embedded_ini_offset = 0x93000,
.embedded_ini_ptr = 0x178,
.free_code_space_offset = 0x67790,
KERNEL_PATCHES(1000)
} }
}; };
@@ -950,7 +855,7 @@ const kernel_info_t *get_kernel_info(void *kernel, size_t size) {
return NULL; return NULL;
} }
void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1, uint32_t target_firmware) { void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1) {
const kernel_info_t *kernel_info = get_kernel_info(_kernel, *kernel_size); const kernel_info_t *kernel_info = get_kernel_info(_kernel, *kernel_size);
*out_ini1 = NULL; *out_ini1 = NULL;
@@ -971,12 +876,6 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel
const uint32_t kernel_ldr_offset = *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr + 8)); const uint32_t kernel_ldr_offset = *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr + 8));
memcpy((void *)((uintptr_t)_kernel + kernel_ldr_offset), kernel_ldr_bin, kernel_ldr_bin_size); memcpy((void *)((uintptr_t)_kernel + kernel_ldr_offset), kernel_ldr_bin, kernel_ldr_bin_size);
/* Set target firmware for our kernel loader. */
uint32_t *kldr_u32 = (uint32_t *)((uintptr_t)_kernel + kernel_ldr_offset);
if (kldr_u32[1] == 0x30444C4D) {
kldr_u32[2] = target_firmware;
}
/* Update size. */ /* Update size. */
*kernel_size = kernel_ldr_offset + kernel_ldr_bin_size; *kernel_size = kernel_ldr_offset + kernel_ldr_bin_size;

View File

@@ -19,6 +19,6 @@
#include "utils.h" #include "utils.h"
void package2_patch_kernel(void *kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1, uint32_t target_firmware); void package2_patch_kernel(void *kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1);
#endif #endif

View File

@@ -160,7 +160,6 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
desired_keyblob = MASTERKEY_REVISION_900; desired_keyblob = MASTERKEY_REVISION_900;
/* Fallthrough */ /* Fallthrough */
case ATMOSPHERE_TARGET_FIRMWARE_910: case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
desired_keyblob = MASTERKEY_REVISION_910_CURRENT; desired_keyblob = MASTERKEY_REVISION_910_CURRENT;
break; break;
default: default:

View File

@@ -232,8 +232,6 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return ATMOSPHERE_TARGET_FIRMWARE_900; return ATMOSPHERE_TARGET_FIRMWARE_900;
} else if (memcmp(package1loader_header->build_timestamp, "20191021", 8) == 0) { } else if (memcmp(package1loader_header->build_timestamp, "20191021", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_910; return ATMOSPHERE_TARGET_FIRMWARE_910;
} else if (memcmp(package1loader_header->build_timestamp, "20200303", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_1000;
} else { } else {
fatal_error("[NXBOOT] Unable to identify package1!\n"); fatal_error("[NXBOOT] Unable to identify package1!\n");
} }

View File

@@ -87,7 +87,7 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
} }
/* Perform any patches we want to the NX kernel. */ /* Perform any patches we want to the NX kernel. */
package2_patch_kernel(kernel, &kernel_size, is_sd_kernel, (void *)&orig_ini1, target_firmware); package2_patch_kernel(kernel, &kernel_size, is_sd_kernel, (void *)&orig_ini1);
/* Ensure we know where embedded INI is if present, and we don't if not. */ /* Ensure we know where embedded INI is if present, and we don't if not. */
if ((target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 != NULL) || if ((target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 != NULL) ||
@@ -232,7 +232,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */ /* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */ /* 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_1000_CURRENT) { if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_910_CURRENT) {
return true; return true;
} }

View File

@@ -39,8 +39,7 @@
#define PACKAGE2_MAXVER_700_800 0xA #define PACKAGE2_MAXVER_700_800 0xA
#define PACKAGE2_MAXVER_810 0xB #define PACKAGE2_MAXVER_810 0xB
#define PACKAGE2_MAXVER_900 0xC #define PACKAGE2_MAXVER_900 0xC
#define PACKAGE2_MAXVER_910_920 0xD #define PACKAGE2_MAXVER_910_CURRENT 0xD
#define PACKAGE2_MAXVER_1000_CURRENT 0xE
#define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_200 0x4
@@ -53,8 +52,7 @@
#define PACKAGE2_MINVER_700_800 0xB #define PACKAGE2_MINVER_700_800 0xB
#define PACKAGE2_MINVER_810 0xC #define PACKAGE2_MINVER_810 0xC
#define PACKAGE2_MINVER_900 0xD #define PACKAGE2_MINVER_900 0xD
#define PACKAGE2_MINVER_910_920 0xE #define PACKAGE2_MINVER_910_CURRENT 0xE
#define PACKAGE2_MINVER_1000_CURRENT 0xF
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull)) #define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master branch = master
commit = 96825c7524c333536dcffadb76341bf599785538 commit = da6eac986d7f67ca3dcc3a8df0c191ffbea4686f
parent = d81a3bdc36ddf3d7b4f3d7fae5cb85afc047b546 parent = eb48e7cc5943bd594b3166cb888d3dadb0474107
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -19,7 +19,6 @@
#include <mesosphere/kern_k_typed_address.hpp> #include <mesosphere/kern_k_typed_address.hpp>
#include <mesosphere/kern_select_cpu.hpp> #include <mesosphere/kern_select_cpu.hpp>
#include <mesosphere/arch/arm64/kern_k_page_table_entry.hpp> #include <mesosphere/arch/arm64/kern_k_page_table_entry.hpp>
#include <mesosphere/kern_select_system_control.hpp>
namespace ams::kern::arch::arm64::init { namespace ams::kern::arch::arm64::init {
@@ -65,220 +64,6 @@ namespace ams::kern::arch::arm64::init {
/* The MMU is necessarily not yet turned on, if we are creating an initial page table. */ /* The MMU is necessarily not yet turned on, if we are creating an initial page table. */
std::memset(reinterpret_cast<void *>(GetInteger(address)), 0, PageSize); std::memset(reinterpret_cast<void *>(GetInteger(address)), 0, PageSize);
} }
private:
size_t NOINLINE GetBlockCount(KVirtualAddress virt_addr, size_t size, size_t block_size) {
const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0;
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(this->l1_table, virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= L1BlockSize);
virt_addr += L1BlockSize;
if (l1_entry->IsBlock() && block_size == L1BlockSize) {
count++;
}
continue;
}
/* Non empty and non-block must be table. */
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
/* Table, so check if we're mapped in L2. */
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
if (l2_entry->IsBlock() || l2_entry->IsEmpty()) {
const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
virt_addr += advance_size;
if (l2_entry->IsBlock() && block_size == advance_size) {
count++;
}
continue;
}
/* Non empty and non-block must be table. */
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
/* Table, so check if we're mapped in L3. */
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
/* L3 must be block or empty. */
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty());
const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
virt_addr += advance_size;
if (l3_entry->IsBlock() && block_size == advance_size) {
count++;
}
}
return count;
}
KVirtualAddress NOINLINE GetBlockByIndex(KVirtualAddress virt_addr, size_t size, size_t block_size, size_t index) {
const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0;
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(this->l1_table, virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= L1BlockSize);
if (l1_entry->IsBlock() && block_size == L1BlockSize) {
if ((count++) == index) {
return virt_addr;
}
}
virt_addr += L1BlockSize;
continue;
}
/* Non empty and non-block must be table. */
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
/* Table, so check if we're mapped in L2. */
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
if (l2_entry->IsBlock() || l2_entry->IsEmpty()) {
const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
if (l2_entry->IsBlock() && block_size == advance_size) {
if ((count++) == index) {
return virt_addr;
}
}
virt_addr += advance_size;
continue;
}
/* Non empty and non-block must be table. */
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
/* Table, so check if we're mapped in L3. */
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
/* L3 must be block or empty. */
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty());
const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
if (l3_entry->IsBlock() && block_size == advance_size) {
if ((count++) == index) {
return virt_addr;
}
}
virt_addr += advance_size;
}
return Null<KVirtualAddress>;
}
PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) {
L1PageTableEntry *l1_entry = GetL1Entry(this->l1_table, virt_addr);
if (l1_entry->IsBlock()) {
MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize);
return l1_entry;
}
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
/* Table, so check if we're mapped in L2. */
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
if (l2_entry->IsBlock()) {
const size_t real_size = (l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size);
return l2_entry;
}
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
/* Table, so check if we're mapped in L3. */
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
/* L3 must be block. */
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock());
const size_t real_size = (l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size);
return l3_entry;
}
void NOINLINE SwapBlocks(KVirtualAddress src_virt_addr, KVirtualAddress dst_virt_addr, size_t block_size, bool do_copy) {
static_assert(L2ContiguousBlockSize / L2BlockSize == L3ContiguousBlockSize / L3BlockSize);
const bool contig = (block_size == L2ContiguousBlockSize || block_size == L3ContiguousBlockSize);
const size_t num_mappings = contig ? L2ContiguousBlockSize / L2BlockSize : 1;
/* Unmap the source. */
PageTableEntry *src_entry = this->GetMappingEntry(src_virt_addr, block_size);
const auto src_saved = *src_entry;
for (size_t i = 0; i < num_mappings; i++) {
*src_entry = InvalidPageTableEntry;
}
/* Unmap the target. */
PageTableEntry *dst_entry = this->GetMappingEntry(dst_virt_addr, block_size);
const auto dst_saved = *dst_entry;
for (size_t i = 0; i < num_mappings; i++) {
*dst_entry = InvalidPageTableEntry;
}
/* Invalidate the entire tlb. */
cpu::DataSynchronizationBarrierInnerShareable();
cpu::InvalidateEntireTlb();
/* Copy data, if we should. */
const u64 negative_block_size_for_mask = static_cast<u64>(-static_cast<s64>(block_size));
const u64 offset_mask = negative_block_size_for_mask & ((1ul << 36) - 1);
const KVirtualAddress copy_src_addr = KVirtualAddress(src_saved.GetRawAttributesUnsafeForSwap() & offset_mask);
const KVirtualAddress copy_dst_addr = KVirtualAddress(dst_saved.GetRawAttributesUnsafeForSwap() & offset_mask);
if (block_size && do_copy) {
u8 tmp[0x100];
for (size_t ofs = 0; ofs < block_size; ofs += sizeof(tmp)) {
std::memcpy(tmp, GetVoidPointer(copy_src_addr + ofs), sizeof(tmp));
std::memcpy(GetVoidPointer(copy_src_addr + ofs), GetVoidPointer(copy_dst_addr + ofs), sizeof(tmp));
std::memcpy(GetVoidPointer(copy_dst_addr + ofs), tmp, sizeof(tmp));
}
}
/* Swap the mappings. */
const u64 attr_preserve_mask = (negative_block_size_for_mask | 0xFFFF000000000000ul) ^ ((1ul << 36) - 1);
const size_t shift_for_contig = contig ? 4 : 0;
size_t advanced_size = 0;
const u64 src_attr_val = src_saved.GetRawAttributesUnsafeForSwap() & attr_preserve_mask;
const u64 dst_attr_val = dst_saved.GetRawAttributesUnsafeForSwap() & attr_preserve_mask;
for (size_t i = 0; i < num_mappings; i++) {
reinterpret_cast<u64 *>(src_entry)[i] = GetInteger(copy_dst_addr + (advanced_size >> shift_for_contig)) | src_attr_val;
reinterpret_cast<u64 *>(dst_entry)[i] = GetInteger(copy_src_addr + (advanced_size >> shift_for_contig)) | dst_attr_val;
advanced_size += block_size;
}
cpu::DataSynchronizationBarrierInnerShareable();
}
void NOINLINE PhysicallyRandomize(KVirtualAddress virt_addr, size_t size, size_t block_size, bool do_copy) {
const size_t block_count = this->GetBlockCount(virt_addr, size, block_size);
if (block_count > 1) {
for (size_t cur_block = 0; cur_block < block_count; cur_block++) {
const size_t target_block = KSystemControl::Init::GenerateRandomRange(cur_block, block_count - 1);
if (cur_block != target_block) {
const KVirtualAddress cur_virt_addr = this->GetBlockByIndex(virt_addr, size, block_size, cur_block);
const KVirtualAddress target_virt_addr = this->GetBlockByIndex(virt_addr, size, block_size, target_block);
MESOSPHERE_INIT_ABORT_UNLESS(cur_virt_addr != Null<KVirtualAddress>);
MESOSPHERE_INIT_ABORT_UNLESS(target_virt_addr != Null<KVirtualAddress>);
this->SwapBlocks(cur_virt_addr, target_virt_addr, block_size, do_copy);
}
}
}
}
public: public:
void NOINLINE Map(KVirtualAddress virt_addr, size_t size, KPhysicalAddress phys_addr, const PageTableEntry &attr, IPageAllocator &allocator) { void NOINLINE Map(KVirtualAddress virt_addr, size_t size, KPhysicalAddress phys_addr, const PageTableEntry &attr, IPageAllocator &allocator) {
/* Ensure that addresses and sizes are page aligned. */ /* Ensure that addresses and sizes are page aligned. */
@@ -578,62 +363,32 @@ namespace ams::kern::arch::arm64::init {
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
} }
void PhysicallyRandomize(KVirtualAddress virt_addr, size_t size, bool do_copy) {
this->PhysicallyRandomize(virt_addr, size, L1BlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L2ContiguousBlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L2BlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L3ContiguousBlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L3BlockSize, do_copy);
}
}; };
class KInitialPageAllocator : public KInitialPageTable::IPageAllocator { class KInitialPageAllocator : public KInitialPageTable::IPageAllocator {
public:
struct State {
uintptr_t next_address;
uintptr_t free_bitmap;
};
private: private:
State state; uintptr_t next_address;
public: public:
constexpr ALWAYS_INLINE KInitialPageAllocator() : state{} { /* ... */ } constexpr ALWAYS_INLINE KInitialPageAllocator() : next_address(Null<uintptr_t>) { /* ... */ }
ALWAYS_INLINE void Initialize(uintptr_t address) { ALWAYS_INLINE void Initialize(uintptr_t address) {
this->state.next_address = address + BITSIZEOF(this->state.free_bitmap) * PageSize; this->next_address = address;
this->state.free_bitmap = ~uintptr_t();
} }
ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) { ALWAYS_INLINE uintptr_t GetFinalNextAddress() {
if (kern::GetTargetFirmware() >= kern::TargetFirmware_10_0_0) { const uintptr_t final_address = this->next_address;
this->state = *reinterpret_cast<State *>(state_val); this->next_address = Null<uintptr_t>;
} else { return final_address;
this->state.next_address = state_val;
this->state.free_bitmap = 0;
}
} }
ALWAYS_INLINE void GetFinalState(State *out) { ALWAYS_INLINE uintptr_t GetFinalState() {
*out = this->state; return this->GetFinalNextAddress();
this->state = {};
} }
public: public:
virtual KPhysicalAddress Allocate() override { virtual KPhysicalAddress Allocate() override {
MESOSPHERE_INIT_ABORT_UNLESS(this->state.next_address != Null<uintptr_t>); MESOSPHERE_INIT_ABORT_UNLESS(this->next_address != Null<uintptr_t>);
uintptr_t allocated = this->state.next_address; const uintptr_t allocated = this->next_address;
if (this->state.free_bitmap != 0) { this->next_address += PageSize;
u64 index;
uintptr_t mask;
do {
index = KSystemControl::Init::GenerateRandomRange(0, BITSIZEOF(this->state.free_bitmap) - 1);
mask = (static_cast<uintptr_t>(1) << index);
} while ((this->state.free_bitmap & mask) == 0);
this->state.free_bitmap &= ~mask;
allocated = this->state.next_address - ((BITSIZEOF(this->state.free_bitmap) - index) * PageSize);
} else {
this->state.next_address += PageSize;
}
std::memset(reinterpret_cast<void *>(allocated), 0, PageSize); std::memset(reinterpret_cast<void *>(allocated), 0, PageSize);
return allocated; return allocated;
} }

View File

@@ -31,12 +31,6 @@ namespace ams::kern::arch::arm64 {
public: public:
struct InvalidTag{}; struct InvalidTag{};
enum ExtensionTag : u64 {
ExtensionTag_IsValidBit = (1ul << 56),
ExtensionTag_IsValid = (ExtensionTag_IsValidBit | (1ul << 0)),
ExtensionTag_IsBlockMask = (ExtensionTag_IsValidBit | (1ul << 1)),
};
enum Permission : u64 { enum Permission : u64 {
Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)), Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)),
Permission_KernelRX = ((0ul << 53) | (1ul << 54) | (2ul << 6)), Permission_KernelRX = ((0ul << 53) | (1ul << 54) | (2ul << 6)),
@@ -95,7 +89,7 @@ namespace ams::kern::arch::arm64 {
/* Construct a new attribute. */ /* Construct a new attribute. */
constexpr ALWAYS_INLINE PageTableEntry(Permission perm, PageAttribute p_a, Shareable share) constexpr ALWAYS_INLINE PageTableEntry(Permission perm, PageAttribute p_a, Shareable share)
: attributes(static_cast<u64>(perm) | static_cast<u64>(AccessFlag_Accessed) | static_cast<u64>(p_a) | static_cast<u64>(share) | static_cast<u64>(ExtensionTag_IsValid)) : attributes(static_cast<u64>(perm) | static_cast<u64>(AccessFlag_Accessed) | static_cast<u64>(p_a) | static_cast<u64>(share))
{ {
/* ... */ /* ... */
} }
@@ -140,9 +134,8 @@ namespace ams::kern::arch::arm64 {
constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; } constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; }
constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; } constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; }
constexpr ALWAYS_INLINE bool IsNonSecure() const { return this->GetBits(5, 1) != 0; } constexpr ALWAYS_INLINE bool IsNonSecure() const { return this->GetBits(5, 1) != 0; }
constexpr ALWAYS_INLINE bool IsBlock() const { return (this->attributes & ExtensionTag_IsBlockMask) == ExtensionTag_IsValidBit; } constexpr ALWAYS_INLINE bool IsBlock() const { return this->GetBits(0, 2) == 0x1; }
constexpr ALWAYS_INLINE bool IsTable() const { return this->GetBits(0, 2) == 0x3; } constexpr ALWAYS_INLINE bool IsTable() const { return this->GetBits(0, 2) == 0x3; }
constexpr ALWAYS_INLINE bool IsEmpty() const { return this->GetBits(0, 2) == 0x0; }
constexpr ALWAYS_INLINE decltype(auto) SetContiguousAllowed(bool en) { this->SetBit(55, !en); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetContiguousAllowed(bool en) { this->SetBit(55, !en); return *this; }
constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; }
@@ -164,10 +157,6 @@ namespace ams::kern::arch::arm64 {
return this->attributes == attr; return this->attributes == attr;
} }
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const {
return this->attributes;
}
protected: protected:
constexpr ALWAYS_INLINE u64 GetRawAttributes() const { constexpr ALWAYS_INLINE u64 GetRawAttributes() const {
return this->attributes; return this->attributes;
@@ -197,7 +186,7 @@ namespace ams::kern::arch::arm64 {
} }
constexpr ALWAYS_INLINE L1PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr ALWAYS_INLINE L1PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionTag_IsValid) : PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x1)
{ {
/* ... */ /* ... */
} }
@@ -242,7 +231,7 @@ namespace ams::kern::arch::arm64 {
} }
constexpr ALWAYS_INLINE L2PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr ALWAYS_INLINE L2PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionTag_IsValid) : PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x1)
{ {
/* ... */ /* ... */
} }
@@ -275,12 +264,12 @@ namespace ams::kern::arch::arm64 {
constexpr ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ } constexpr ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ }
constexpr ALWAYS_INLINE L3PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr ALWAYS_INLINE L3PageTableEntry(KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x2 | PageTableEntry::ExtensionTag_IsValid) : PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x3)
{ {
/* ... */ /* ... */
} }
constexpr ALWAYS_INLINE bool IsBlock() const { return (GetRawAttributes() & ExtensionTag_IsBlockMask) == ExtensionTag_IsBlockMask; } constexpr ALWAYS_INLINE bool IsBlock() const { return this->GetBits(0, 2) == 0x3; }
constexpr ALWAYS_INLINE KPhysicalAddress GetBlock() const { constexpr ALWAYS_INLINE KPhysicalAddress GetBlock() const {
return this->SelectBits(12, 36); return this->SelectBits(12, 36);

View File

@@ -20,24 +20,6 @@ namespace ams::kern {
constexpr size_t PageSize = 4_KB; constexpr size_t PageSize = 4_KB;
enum TargetFirmware : u32 {
TargetFirmware_1_0_0 = ATMOSPHERE_TARGET_FIRMWARE_100,
TargetFirmware_2_0_0 = ATMOSPHERE_TARGET_FIRMWARE_200,
TargetFirmware_3_0_0 = ATMOSPHERE_TARGET_FIRMWARE_300,
TargetFirmware_4_0_0 = ATMOSPHERE_TARGET_FIRMWARE_400,
TargetFirmware_5_0_0 = ATMOSPHERE_TARGET_FIRMWARE_500,
TargetFirmware_6_0_0 = ATMOSPHERE_TARGET_FIRMWARE_600,
TargetFirmware_6_2_0 = ATMOSPHERE_TARGET_FIRMWARE_620,
TargetFirmware_7_0_0 = ATMOSPHERE_TARGET_FIRMWARE_700,
TargetFirmware_8_0_0 = ATMOSPHERE_TARGET_FIRMWARE_800,
TargetFirmware_8_1_0 = ATMOSPHERE_TARGET_FIRMWARE_810,
TargetFirmware_9_0_0 = ATMOSPHERE_TARGET_FIRMWARE_900,
TargetFirmware_9_1_0 = ATMOSPHERE_TARGET_FIRMWARE_910,
TargetFirmware_10_0_0 = ATMOSPHERE_TARGET_FIRMWARE_1000,
};
TargetFirmware GetTargetFirmware();
} }
#if 1 || defined(AMS_BUILD_FOR_AUDITING) #if 1 || defined(AMS_BUILD_FOR_AUDITING)

View File

@@ -51,7 +51,6 @@
#include <stratosphere/ncm.hpp> #include <stratosphere/ncm.hpp>
#include <stratosphere/nim.hpp> #include <stratosphere/nim.hpp>
#include <stratosphere/patcher.hpp> #include <stratosphere/patcher.hpp>
#include <stratosphere/pgl.hpp>
#include <stratosphere/psc.hpp> #include <stratosphere/psc.hpp>
#include <stratosphere/pm.hpp> #include <stratosphere/pm.hpp>
#include <stratosphere/reg.hpp> #include <stratosphere/reg.hpp>

View File

@@ -35,7 +35,6 @@ namespace ams::exosphere {
AMS_DEFINE_TARGET_FIRMWARE_ENUM(810), AMS_DEFINE_TARGET_FIRMWARE_ENUM(810),
AMS_DEFINE_TARGET_FIRMWARE_ENUM(900), AMS_DEFINE_TARGET_FIRMWARE_ENUM(900),
AMS_DEFINE_TARGET_FIRMWARE_ENUM(910), AMS_DEFINE_TARGET_FIRMWARE_ENUM(910),
AMS_DEFINE_TARGET_FIRMWARE_ENUM(1000),
}; };
#undef AMS_DEFINE_TARGET_FIRMWARE_ENUM #undef AMS_DEFINE_TARGET_FIRMWARE_ENUM

View File

@@ -54,15 +54,15 @@ namespace ams::erpt::sf {
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(SubmitContext), MAKE_SERVICE_COMMAND_META(SubmitContext),
MAKE_SERVICE_COMMAND_META(CreateReport), MAKE_SERVICE_COMMAND_META(CreateReport),
MAKE_SERVICE_COMMAND_META(SetInitialLaunchSettingsCompletionTime, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(SetInitialLaunchSettingsCompletionTime, hos::Version_300),
MAKE_SERVICE_COMMAND_META(ClearInitialLaunchSettingsCompletionTime, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(ClearInitialLaunchSettingsCompletionTime, hos::Version_300),
MAKE_SERVICE_COMMAND_META(UpdatePowerOnTime, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(UpdatePowerOnTime, hos::Version_300),
MAKE_SERVICE_COMMAND_META(UpdateAwakeTime, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(UpdateAwakeTime, hos::Version_300),
MAKE_SERVICE_COMMAND_META(SubmitMultipleCategoryContext, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(SubmitMultipleCategoryContext, hos::Version_500),
MAKE_SERVICE_COMMAND_META(UpdateApplicationLaunchTime, hos::Version_6_0_0), MAKE_SERVICE_COMMAND_META(UpdateApplicationLaunchTime, hos::Version_600),
MAKE_SERVICE_COMMAND_META(ClearApplicationLaunchTime, hos::Version_6_0_0), MAKE_SERVICE_COMMAND_META(ClearApplicationLaunchTime, hos::Version_600),
MAKE_SERVICE_COMMAND_META(SubmitAttachment, hos::Version_8_0_0), MAKE_SERVICE_COMMAND_META(SubmitAttachment, hos::Version_800),
MAKE_SERVICE_COMMAND_META(CreateReportWithAttachments, hos::Version_8_0_0), MAKE_SERVICE_COMMAND_META(CreateReportWithAttachments, hos::Version_800),
}; };
}; };

View File

@@ -41,10 +41,10 @@ namespace ams::erpt::sf {
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(GetReportList), MAKE_SERVICE_COMMAND_META(GetReportList),
MAKE_SERVICE_COMMAND_META(GetEvent), MAKE_SERVICE_COMMAND_META(GetEvent),
MAKE_SERVICE_COMMAND_META(CleanupReports, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(CleanupReports, hos::Version_400),
MAKE_SERVICE_COMMAND_META(DeleteReport, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(DeleteReport, hos::Version_500),
MAKE_SERVICE_COMMAND_META(GetStorageUsageStatistics, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(GetStorageUsageStatistics, hos::Version_500),
MAKE_SERVICE_COMMAND_META(GetAttachmentList, hos::Version_8_0_0), MAKE_SERVICE_COMMAND_META(GetAttachmentList, hos::Version_800),
}; };
}; };

View File

@@ -38,7 +38,7 @@ namespace ams::erpt::sf {
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(OpenReport), MAKE_SERVICE_COMMAND_META(OpenReport),
MAKE_SERVICE_COMMAND_META(OpenManager), MAKE_SERVICE_COMMAND_META(OpenManager),
MAKE_SERVICE_COMMAND_META(OpenAttachment, hos::Version_8_0_0), MAKE_SERVICE_COMMAND_META(OpenAttachment, hos::Version_800),
}; };
}; };

View File

@@ -19,17 +19,9 @@
namespace ams::fs { namespace ams::fs {
struct CodeInfo { Result MountCode(const char *name, const char *path, ncm::ProgramId program_id);
u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize];
u8 hash[crypto::Rsa2048PssSha256Verifier::HashSize];
bool is_signed;
u8 reserved[3];
};
static_assert(sizeof(CodeInfo) == crypto::Rsa2048PssSha256Verifier::SignatureSize + crypto::Rsa2048PssSha256Verifier::HashSize + 4);
Result MountCode(CodeInfo *out, const char *name, const char *path, ncm::ProgramId program_id); Result MountCodeForAtmosphereWithRedirection(const char *name, const char *path, ncm::ProgramId program_id, bool is_hbl, bool is_specific);
Result MountCodeForAtmosphere(const char *name, const char *path, ncm::ProgramId program_id);
Result MountCodeForAtmosphereWithRedirection(CodeInfo *out, const char *name, const char *path, ncm::ProgramId program_id, bool is_hbl, bool is_specific);
Result MountCodeForAtmosphere(CodeInfo *out, const char *name, const char *path, ncm::ProgramId program_id);
} }

View File

@@ -72,7 +72,7 @@ namespace ams::fssrv::impl {
MAKE_SERVICE_COMMAND_META(GetSize), MAKE_SERVICE_COMMAND_META(GetSize),
/* 4.0.0- */ /* 4.0.0- */
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
}; };
}; };
@@ -181,11 +181,11 @@ namespace ams::fssrv::impl {
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize), MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize),
/* 3.0.0- */ /* 3.0.0- */
MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_300),
/* 4.0.0- */ /* 4.0.0- */
MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_400),
}; };
}; };

View File

@@ -71,7 +71,7 @@ namespace ams::fssrv::impl {
MAKE_SERVICE_COMMAND_META(GetSize), MAKE_SERVICE_COMMAND_META(GetSize),
/* 4.0.0- */ /* 4.0.0- */
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
}; };
}; };

View File

@@ -17,7 +17,6 @@
#pragma once #pragma once
#include <stratosphere/fssystem/fssystem_utility.hpp> #include <stratosphere/fssystem/fssystem_utility.hpp>
#include <stratosphere/fssystem/fssystem_external_code.hpp> #include <stratosphere/fssystem/fssystem_external_code.hpp>
#include <stratosphere/fssystem/fssystem_acid_sign_key.hpp>
#include <stratosphere/fssystem/fssystem_partition_file_system.hpp> #include <stratosphere/fssystem/fssystem_partition_file_system.hpp>
#include <stratosphere/fssystem/fssystem_partition_file_system_meta.hpp> #include <stratosphere/fssystem/fssystem_partition_file_system_meta.hpp>
#include <stratosphere/fssystem/fssystem_path_tool.hpp> #include <stratosphere/fssystem/fssystem_path_tool.hpp>

View File

@@ -1,111 +0,0 @@
/*
* 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::fssystem {
constexpr inline size_t AcidSignatureKeyGenerationMax = 1;
constexpr inline size_t AcidSignatureKeyModulusSize = 0x100;
constexpr inline const u8 AcidSignatureKeyModulusDev[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = {
{
0xD6, 0x34, 0xA5, 0x78, 0x6C, 0x68, 0xCE, 0x5A, 0xC2, 0x37, 0x17, 0xF3, 0x82, 0x45, 0xC6, 0x89,
0xE1, 0x2D, 0x06, 0x67, 0xBF, 0xB4, 0x06, 0x19, 0x55, 0x6B, 0x27, 0x66, 0x0C, 0xA4, 0xB5, 0x87,
0x81, 0x25, 0xF4, 0x30, 0xBC, 0x53, 0x08, 0x68, 0xA2, 0x48, 0x49, 0x8C, 0x3F, 0x38, 0x40, 0x9C,
0xC4, 0x26, 0xF4, 0x79, 0xE2, 0xA1, 0x85, 0xF5, 0x5C, 0x7F, 0x58, 0xBA, 0xA6, 0x1C, 0xA0, 0x8B,
0x84, 0x16, 0x14, 0x6F, 0x85, 0xD9, 0x7C, 0xE1, 0x3C, 0x67, 0x22, 0x1E, 0xFB, 0xD8, 0xA7, 0xA5,
0x9A, 0xBF, 0xEC, 0x0E, 0xCF, 0x96, 0x7E, 0x85, 0xC2, 0x1D, 0x49, 0x5D, 0x54, 0x26, 0xCB, 0x32,
0x7C, 0xF6, 0xBB, 0x58, 0x03, 0x80, 0x2B, 0x5D, 0xF7, 0xFB, 0xD1, 0x9D, 0xC7, 0xC6, 0x2E, 0x53,
0xC0, 0x6F, 0x39, 0x2C, 0x1F, 0xA9, 0x92, 0xF2, 0x4D, 0x7D, 0x4E, 0x74, 0xFF, 0xE4, 0xEF, 0xE4,
0x7C, 0x3D, 0x34, 0x2A, 0x71, 0xA4, 0x97, 0x59, 0xFF, 0x4F, 0xA2, 0xF4, 0x66, 0x78, 0xD8, 0xBA,
0x99, 0xE3, 0xE6, 0xDB, 0x54, 0xB9, 0xE9, 0x54, 0xA1, 0x70, 0xFC, 0x05, 0x1F, 0x11, 0x67, 0x4B,
0x26, 0x8C, 0x0C, 0x3E, 0x03, 0xD2, 0xA3, 0x55, 0x5C, 0x7D, 0xC0, 0x5D, 0x9D, 0xFF, 0x13, 0x2F,
0xFD, 0x19, 0xBF, 0xED, 0x44, 0xC3, 0x8C, 0xA7, 0x28, 0xCB, 0xE5, 0xE0, 0xB1, 0xA7, 0x9C, 0x33,
0x8D, 0xB8, 0x6E, 0xDE, 0x87, 0x18, 0x22, 0x60, 0xC4, 0xAE, 0xF2, 0x87, 0x9F, 0xCE, 0x09, 0x5C,
0xB5, 0x99, 0xA5, 0x9F, 0x49, 0xF2, 0xD7, 0x58, 0xFA, 0xF9, 0xC0, 0x25, 0x7D, 0xD6, 0xCB, 0xF3,
0xD8, 0x6C, 0xA2, 0x69, 0x91, 0x68, 0x73, 0xB1, 0x94, 0x6F, 0xA3, 0xF3, 0xB9, 0x7D, 0xF8, 0xE0,
0x72, 0x9E, 0x93, 0x7B, 0x7A, 0xA2, 0x57, 0x60, 0xB7, 0x5B, 0xA9, 0x84, 0xAE, 0x64, 0x88, 0x69
},
{
0xBC, 0xA5, 0x6A, 0x7E, 0xEA, 0x38, 0x34, 0x62, 0xA6, 0x10, 0x18, 0x3C, 0xE1, 0x63, 0x7B, 0xF0,
0xD3, 0x08, 0x8C, 0xF5, 0xC5, 0xC4, 0xC7, 0x93, 0xE9, 0xD9, 0xE6, 0x32, 0xF3, 0xA0, 0xF6, 0x6E,
0x8A, 0x98, 0x76, 0x47, 0x33, 0x47, 0x65, 0x02, 0x70, 0xDC, 0x86, 0x5F, 0x3D, 0x61, 0x5A, 0x70,
0xBC, 0x5A, 0xCA, 0xCA, 0x50, 0xAD, 0x61, 0x7E, 0xC9, 0xEC, 0x27, 0xFF, 0xE8, 0x64, 0x42, 0x9A,
0xEE, 0xBE, 0xC3, 0xD1, 0x0B, 0xC0, 0xE9, 0xBF, 0x83, 0x8D, 0xC0, 0x0C, 0xD8, 0x00, 0x5B, 0x76,
0x90, 0xD2, 0x4B, 0x30, 0x84, 0x35, 0x8B, 0x1E, 0x20, 0xB7, 0xE4, 0xDC, 0x63, 0xE5, 0xDF, 0xCD,
0x00, 0x5F, 0x81, 0x5F, 0x67, 0xC5, 0x8B, 0xDF, 0xFC, 0xE1, 0x37, 0x5F, 0x07, 0xD9, 0xDE, 0x4F,
0xE6, 0x7B, 0xF1, 0xFB, 0xA1, 0x5A, 0x71, 0x40, 0xFE, 0xBA, 0x1E, 0xAE, 0x13, 0x22, 0xD2, 0xFE,
0x37, 0xA2, 0xB6, 0x8B, 0xAB, 0xEB, 0x84, 0x81, 0x4E, 0x7C, 0x1E, 0x02, 0xD1, 0xFB, 0xD7, 0x5D,
0x11, 0x84, 0x64, 0xD2, 0x4D, 0xBB, 0x50, 0x00, 0x67, 0x54, 0xE2, 0x77, 0x89, 0xBA, 0x0B, 0xE7,
0x05, 0x57, 0x9A, 0x22, 0x5A, 0xEC, 0x76, 0x1C, 0xFD, 0xE8, 0xA8, 0x18, 0x16, 0x41, 0x65, 0x03,
0xFA, 0xC4, 0xA6, 0x31, 0x5C, 0x1A, 0x7F, 0xAB, 0x11, 0xC8, 0x4A, 0x99, 0xB9, 0xE6, 0xCF, 0x62,
0x21, 0xA6, 0x72, 0x47, 0xDB, 0xBA, 0x96, 0x26, 0x4E, 0x2E, 0xD4, 0x8C, 0x46, 0xD6, 0xA7, 0x1A,
0x6C, 0x32, 0xA7, 0xDF, 0x85, 0x1C, 0x03, 0xC3, 0x6D, 0xA9, 0xE9, 0x68, 0xF4, 0x17, 0x1E, 0xB2,
0x70, 0x2A, 0xA1, 0xE5, 0xE1, 0xF3, 0x8F, 0x6F, 0x63, 0xAC, 0xEB, 0x72, 0x0B, 0x4C, 0x4A, 0x36,
0x3C, 0x60, 0x91, 0x9F, 0x6E, 0x1C, 0x71, 0xEA, 0xD0, 0x78, 0x78, 0xA0, 0x2E, 0xC6, 0x32, 0x6B
}
};
constexpr inline const u8 AcidSignatureKeyModulusProd[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = {
{
0xDD, 0xC8, 0xDD, 0xF2, 0x4E, 0x6D, 0xF0, 0xCA, 0x9E, 0xC7, 0x5D, 0xC7, 0x7B, 0xAD, 0xFE, 0x7D,
0x23, 0x89, 0x69, 0xB6, 0xF2, 0x06, 0xA2, 0x02, 0x88, 0xE1, 0x55, 0x91, 0xAB, 0xCB, 0x4D, 0x50,
0x2E, 0xFC, 0x9D, 0x94, 0x76, 0xD6, 0x4C, 0xD8, 0xFF, 0x10, 0xFA, 0x5E, 0x93, 0x0A, 0xB4, 0x57,
0xAC, 0x51, 0xC7, 0x16, 0x66, 0xF4, 0x1A, 0x54, 0xC2, 0xC5, 0x04, 0x3D, 0x1B, 0xFE, 0x30, 0x20,
0x8A, 0xAC, 0x6F, 0x6F, 0xF5, 0xC7, 0xB6, 0x68, 0xB8, 0xC9, 0x40, 0x6B, 0x42, 0xAD, 0x11, 0x21,
0xE7, 0x8B, 0xE9, 0x75, 0x01, 0x86, 0xE4, 0x48, 0x9B, 0x0A, 0x0A, 0xF8, 0x7F, 0xE8, 0x87, 0xF2,
0x82, 0x01, 0xE6, 0xA3, 0x0F, 0xE4, 0x66, 0xAE, 0x83, 0x3F, 0x4E, 0x9F, 0x5E, 0x01, 0x30, 0xA4,
0x00, 0xB9, 0x9A, 0xAE, 0x5F, 0x03, 0xCC, 0x18, 0x60, 0xE5, 0xEF, 0x3B, 0x5E, 0x15, 0x16, 0xFE,
0x1C, 0x82, 0x78, 0xB5, 0x2F, 0x47, 0x7C, 0x06, 0x66, 0x88, 0x5D, 0x35, 0xA2, 0x67, 0x20, 0x10,
0xE7, 0x6C, 0x43, 0x68, 0xD3, 0xE4, 0x5A, 0x68, 0x2A, 0x5A, 0xE2, 0x6D, 0x73, 0xB0, 0x31, 0x53,
0x1C, 0x20, 0x09, 0x44, 0xF5, 0x1A, 0x9D, 0x22, 0xBE, 0x12, 0xA1, 0x77, 0x11, 0xE2, 0xA1, 0xCD,
0x40, 0x9A, 0xA2, 0x8B, 0x60, 0x9B, 0xEF, 0xA0, 0xD3, 0x48, 0x63, 0xA2, 0xF8, 0xA3, 0x2C, 0x08,
0x56, 0x52, 0x2E, 0x60, 0x19, 0x67, 0x5A, 0xA7, 0x9F, 0xDC, 0x3F, 0x3F, 0x69, 0x2B, 0x31, 0x6A,
0xB7, 0x88, 0x4A, 0x14, 0x84, 0x80, 0x33, 0x3C, 0x9D, 0x44, 0xB7, 0x3F, 0x4C, 0xE1, 0x75, 0xEA,
0x37, 0xEA, 0xE8, 0x1E, 0x7C, 0x77, 0xB7, 0xC6, 0x1A, 0xA2, 0xF0, 0x9F, 0x10, 0x61, 0xCD, 0x7B,
0x5B, 0x32, 0x4C, 0x37, 0xEF, 0xB1, 0x71, 0x68, 0x53, 0x0A, 0xED, 0x51, 0x7D, 0x35, 0x22, 0xFD
},
{
0xE7, 0xAA, 0x25, 0xC8, 0x01, 0xA5, 0x14, 0x6B, 0x01, 0x60, 0x3E, 0xD9, 0x96, 0x5A, 0xBF, 0x90,
0xAC, 0xA7, 0xFD, 0x9B, 0x5B, 0xBD, 0x8A, 0x26, 0xB0, 0xCB, 0x20, 0x28, 0x9A, 0x72, 0x12, 0xF5,
0x20, 0x65, 0xB3, 0xB9, 0x84, 0x58, 0x1F, 0x27, 0xBC, 0x7C, 0xA2, 0xC9, 0x9E, 0x18, 0x95, 0xCF,
0xC2, 0x73, 0x2E, 0x74, 0x8C, 0x66, 0xE5, 0x9E, 0x79, 0x2B, 0xB8, 0x07, 0x0C, 0xB0, 0x4E, 0x8E,
0xAB, 0x85, 0x21, 0x42, 0xC4, 0xC5, 0x6D, 0x88, 0x9C, 0xDB, 0x15, 0x95, 0x3F, 0x80, 0xDB, 0x7A,
0x9A, 0x7D, 0x41, 0x56, 0x25, 0x17, 0x18, 0x42, 0x4D, 0x8C, 0xAC, 0xA5, 0x7B, 0xDB, 0x42, 0x5D,
0x59, 0x35, 0x45, 0x5D, 0x8A, 0x02, 0xB5, 0x70, 0xC0, 0x72, 0x35, 0x46, 0xD0, 0x1D, 0x60, 0x01,
0x4A, 0xCC, 0x1C, 0x46, 0xD3, 0xD6, 0x35, 0x52, 0xD6, 0xE1, 0xF8, 0x3B, 0x5D, 0xEA, 0xDD, 0xB8,
0xFE, 0x7D, 0x50, 0xCB, 0x35, 0x23, 0x67, 0x8B, 0xB6, 0xE4, 0x74, 0xD2, 0x60, 0xFC, 0xFD, 0x43,
0xBF, 0x91, 0x08, 0x81, 0xC5, 0x4F, 0x5D, 0x16, 0x9A, 0xC4, 0x9A, 0xC6, 0xF6, 0xF3, 0xE1, 0xF6,
0x5C, 0x07, 0xAA, 0x71, 0x6C, 0x13, 0xA4, 0xB1, 0xB3, 0x66, 0xBF, 0x90, 0x4C, 0x3D, 0xA2, 0xC4,
0x0B, 0xB8, 0x3D, 0x7A, 0x8C, 0x19, 0xFA, 0xFF, 0x6B, 0xB9, 0x1F, 0x02, 0xCC, 0xB6, 0xD3, 0x0C,
0x7D, 0x19, 0x1F, 0x47, 0xF9, 0xC7, 0x40, 0x01, 0xFA, 0x46, 0xEA, 0x0B, 0xD4, 0x02, 0xE0, 0x3D,
0x30, 0x9A, 0x1A, 0x0F, 0xEA, 0xA7, 0x66, 0x55, 0xF7, 0xCB, 0x28, 0xE2, 0xBB, 0x99, 0xE4, 0x83,
0xC3, 0x43, 0x03, 0xEE, 0xDC, 0x1F, 0x02, 0x23, 0xDD, 0xD1, 0x2D, 0x39, 0xA4, 0x65, 0x75, 0x03,
0xEF, 0x37, 0x9C, 0x06, 0xD6, 0xFA, 0xA1, 0x15, 0xF0, 0xDB, 0x17, 0x47, 0x26, 0x4F, 0x49, 0x03
}
};
static_assert(sizeof(AcidSignatureKeyModulusProd) == sizeof(AcidSignatureKeyModulusDev));
constexpr inline const u8 AcidSignatureKeyExponent[] = {
0x01, 0x00, 0x01
};
constexpr inline size_t AcidSignatureKeyExponentSize = util::size(AcidSignatureKeyExponent);
}

View File

@@ -20,20 +20,19 @@
namespace ams::hos { namespace ams::hos {
enum Version : u16 { enum Version : u16 {
Version_Min = 0, Version_Min = 0,
Version_1_0_0 = Version_Min, Version_100 = Version_Min,
Version_2_0_0 = 1, Version_200 = 1,
Version_3_0_0 = 2, Version_300 = 2,
Version_4_0_0 = 3, Version_400 = 3,
Version_5_0_0 = 4, Version_500 = 4,
Version_6_0_0 = 5, Version_600 = 5,
Version_7_0_0 = 6, Version_700 = 6,
Version_8_0_0 = 7, Version_800 = 7,
Version_8_1_0 = 8, Version_810 = 8,
Version_9_0_0 = 9, Version_900 = 9,
Version_9_1_0 = 10, Version_910 = 10,
Version_10_0_0 = 11, Version_Current = Version_910,
Version_Current = Version_10_0_0,
Version_Max = 32, Version_Max = 32,
}; };

View File

@@ -16,6 +16,5 @@
#pragma once #pragma once
#include <stratosphere/ldr/ldr_types.hpp> #include "ldr/ldr_types.hpp"
#include <stratosphere/ldr/ldr_shell_api.hpp> #include "ldr/ldr_pm_api.hpp"
#include <stratosphere/ldr/ldr_pm_api.hpp>

View File

@@ -24,7 +24,6 @@ namespace ams::ldr::pm {
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc); Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc);
Result UnpinProgram(PinId pin_id); Result UnpinProgram(PinId pin_id);
Result SetEnabledProgramVerification(bool enabled);
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id); Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id);
/* Atmosphere extension API. */ /* Atmosphere extension API. */

View File

@@ -1,31 +0,0 @@
/*
* 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/ldr/ldr_types.hpp>
namespace ams::ldr {
/* Shell API. */
Result InitializeForShell();
Result FinalizeForShell();
Result SetProgramArgument(ncm::ProgramId program_id, const void *arg, size_t size);
Result FlushArguments();
}

View File

@@ -221,8 +221,7 @@ namespace ams::ldr {
}; };
u32 magic; u32 magic;
u32 signature_key_generation; u8 reserved_04[8];
u8 reserved_08[4];
u8 flags; u8 flags;
u8 reserved_0D; u8 reserved_0D;
u8 main_thread_priority; u8 main_thread_priority;

View File

@@ -49,7 +49,7 @@ namespace ams::lr {
Result RegisterAddOnContentStorage(ncm::DataId id, ncm::ApplicationId application_id, ncm::StorageId storage_id) { Result RegisterAddOnContentStorage(ncm::DataId id, ncm::ApplicationId application_id, ncm::StorageId storage_id) {
AMS_ASSERT(this->interface); AMS_ASSERT(this->interface);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
return this->interface->RegisterAddOnContentStorage(id, application_id, storage_id); return this->interface->RegisterAddOnContentStorage(id, application_id, storage_id);
} else { } else {
return this->interface->RegisterAddOnContentStorageDeprecated(id, storage_id); return this->interface->RegisterAddOnContentStorageDeprecated(id, storage_id);

View File

@@ -39,12 +39,12 @@ namespace ams::lr {
virtual Result UnregisterApplicationAddOnContent(ncm::ApplicationId id) = 0; virtual Result UnregisterApplicationAddOnContent(ncm::ApplicationId id) = 0;
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(ResolveAddOnContentPath, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(ResolveAddOnContentPath, hos::Version_200),
MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorageDeprecated, hos::Version_2_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorageDeprecated, hos::Version_200, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorage, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorage, hos::Version_900),
MAKE_SERVICE_COMMAND_META(UnregisterAllAddOnContentPath, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(UnregisterAllAddOnContentPath, hos::Version_200),
MAKE_SERVICE_COMMAND_META(RefreshApplicationAddOnContent, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RefreshApplicationAddOnContent, hos::Version_900),
MAKE_SERVICE_COMMAND_META(UnregisterApplicationAddOnContent, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(UnregisterApplicationAddOnContent, hos::Version_900),
}; };
}; };

View File

@@ -88,27 +88,27 @@ namespace ams::lr {
MAKE_SERVICE_COMMAND_META(ResolveApplicationControlPath), MAKE_SERVICE_COMMAND_META(ResolveApplicationControlPath),
MAKE_SERVICE_COMMAND_META(ResolveApplicationHtmlDocumentPath), MAKE_SERVICE_COMMAND_META(ResolveApplicationHtmlDocumentPath),
MAKE_SERVICE_COMMAND_META(ResolveDataPath), MAKE_SERVICE_COMMAND_META(ResolveDataPath),
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPathDeprecated, hos::Version_1_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPathDeprecated, hos::Version_100, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPathDeprecated, hos::Version_1_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPathDeprecated, hos::Version_100, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(ResolveApplicationLegalInformationPath), MAKE_SERVICE_COMMAND_META(ResolveApplicationLegalInformationPath),
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPathDeprecated, hos::Version_1_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPathDeprecated, hos::Version_100, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(Refresh), MAKE_SERVICE_COMMAND_META(Refresh),
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathDeprecated, hos::Version_5_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathDeprecated, hos::Version_500, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirectionDeprecated, hos::Version_5_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(ClearApplicationRedirectionDeprecated, hos::Version_500, hos::Version_810),
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirection, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(ClearApplicationRedirection, hos::Version_900),
MAKE_SERVICE_COMMAND_META(EraseProgramRedirection, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(EraseProgramRedirection, hos::Version_500),
MAKE_SERVICE_COMMAND_META(EraseApplicationControlRedirection, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(EraseApplicationControlRedirection, hos::Version_500),
MAKE_SERVICE_COMMAND_META(EraseApplicationHtmlDocumentRedirection, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(EraseApplicationHtmlDocumentRedirection, hos::Version_500),
MAKE_SERVICE_COMMAND_META(EraseApplicationLegalInformationRedirection, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(EraseApplicationLegalInformationRedirection, hos::Version_500),
MAKE_SERVICE_COMMAND_META(ResolveProgramPathForDebug, hos::Version_7_0_0), MAKE_SERVICE_COMMAND_META(ResolveProgramPathForDebug, hos::Version_700),
MAKE_SERVICE_COMMAND_META(RedirectProgramPathForDebug, hos::Version_7_0_0), MAKE_SERVICE_COMMAND_META(RedirectProgramPathForDebug, hos::Version_700),
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebugDeprecated, hos::Version_7_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebugDeprecated, hos::Version_700, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebug, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebug, hos::Version_900),
MAKE_SERVICE_COMMAND_META(EraseProgramRedirectionForDebug, hos::Version_7_0_0), MAKE_SERVICE_COMMAND_META(EraseProgramRedirectionForDebug, hos::Version_700),
}; };
}; };

View File

@@ -56,19 +56,19 @@ namespace ams::lr {
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(ResolveProgramPath), MAKE_SERVICE_COMMAND_META(ResolveProgramPath),
MAKE_SERVICE_COMMAND_META(RegisterProgramPathDeprecated, hos::Version_1_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RegisterProgramPathDeprecated, hos::Version_100, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RegisterProgramPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RegisterProgramPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(UnregisterProgramPath), MAKE_SERVICE_COMMAND_META(UnregisterProgramPath),
MAKE_SERVICE_COMMAND_META(RedirectProgramPathDeprecated, hos::Version_1_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectProgramPathDeprecated, hos::Version_100, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectProgramPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectProgramPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(ResolveHtmlDocumentPath, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(ResolveHtmlDocumentPath, hos::Version_200),
MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPathDeprecated, hos::Version_2_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPathDeprecated, hos::Version_200, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(UnregisterHtmlDocumentPath, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(UnregisterHtmlDocumentPath, hos::Version_200),
MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPathDeprecated, hos::Version_2_0_0, hos::Version_8_1_0), MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPathDeprecated, hos::Version_200, hos::Version_810),
MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPath, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPath, hos::Version_900),
MAKE_SERVICE_COMMAND_META(Refresh, hos::Version_7_0_0), MAKE_SERVICE_COMMAND_META(Refresh, hos::Version_700),
MAKE_SERVICE_COMMAND_META(RefreshExcluding, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(RefreshExcluding, hos::Version_900),
}; };
}; };

View File

@@ -68,7 +68,7 @@ namespace ams::lr {
void RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectApplicationControlPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectApplicationControlPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectApplicationControlPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectApplicationControlPathDeprecated(path, id));
@@ -77,7 +77,7 @@ namespace ams::lr {
void RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectApplicationHtmlDocumentPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectApplicationHtmlDocumentPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectApplicationHtmlDocumentPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectApplicationHtmlDocumentPathDeprecated(path, id));
@@ -91,7 +91,7 @@ namespace ams::lr {
void RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectApplicationLegalInformationPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectApplicationLegalInformationPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectApplicationLegalInformationPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectApplicationLegalInformationPathDeprecated(path, id));
@@ -105,7 +105,7 @@ namespace ams::lr {
void RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathDeprecated(path, id));
@@ -114,13 +114,13 @@ namespace ams::lr {
Result ClearApplicationRedirection() { Result ClearApplicationRedirection() {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
AMS_ASSERT(hos::GetVersion() < hos::Version_9_0_0); AMS_ASSERT(hos::GetVersion() < hos::Version_900);
return this->ClearApplicationRedirection(nullptr, 0); return this->ClearApplicationRedirection(nullptr, 0);
} }
Result ClearApplicationRedirection(const ncm::ProgramId *excluding_ids, size_t num_ids) { Result ClearApplicationRedirection(const ncm::ProgramId *excluding_ids, size_t num_ids) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
return this->interface->ClearApplicationRedirection(sf::InArray<ncm::ProgramId>(excluding_ids, num_ids)); return this->interface->ClearApplicationRedirection(sf::InArray<ncm::ProgramId>(excluding_ids, num_ids));
} else { } else {
return this->interface->ClearApplicationRedirectionDeprecated(); return this->interface->ClearApplicationRedirectionDeprecated();
@@ -159,7 +159,7 @@ namespace ams::lr {
void RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathForDebug(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathForDebug(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathForDebugDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectApplicationProgramPathForDebugDeprecated(path, id));

View File

@@ -40,7 +40,7 @@ namespace ams::lr {
MAKE_SERVICE_COMMAND_META(OpenLocationResolver), MAKE_SERVICE_COMMAND_META(OpenLocationResolver),
MAKE_SERVICE_COMMAND_META(OpenRegisteredLocationResolver), MAKE_SERVICE_COMMAND_META(OpenRegisteredLocationResolver),
MAKE_SERVICE_COMMAND_META(RefreshLocationResolver), MAKE_SERVICE_COMMAND_META(RefreshLocationResolver),
MAKE_SERVICE_COMMAND_META(OpenAddOnContentLocationResolver, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(OpenAddOnContentLocationResolver, hos::Version_200),
}; };
}; };

View File

@@ -49,7 +49,7 @@ namespace ams::lr {
Result RegisterProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { Result RegisterProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface); AMS_ASSERT(this->interface);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
return this->interface->RegisterProgramPath(path, id, owner_id); return this->interface->RegisterProgramPath(path, id, owner_id);
} else { } else {
return this->interface->RegisterProgramPathDeprecated(path, id); return this->interface->RegisterProgramPathDeprecated(path, id);
@@ -63,7 +63,7 @@ namespace ams::lr {
void RedirectProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface); AMS_ASSERT(this->interface);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectProgramPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectProgramPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectProgramPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectProgramPathDeprecated(path, id));
@@ -77,7 +77,7 @@ namespace ams::lr {
Result RegisterHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { Result RegisterHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface); AMS_ASSERT(this->interface);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
return this->interface->RegisterHtmlDocumentPath(path, id, owner_id); return this->interface->RegisterHtmlDocumentPath(path, id, owner_id);
} else { } else {
return this->interface->RegisterHtmlDocumentPathDeprecated(path, id); return this->interface->RegisterHtmlDocumentPathDeprecated(path, id);
@@ -91,7 +91,7 @@ namespace ams::lr {
void RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) { void RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
AMS_ASSERT(this->interface); AMS_ASSERT(this->interface);
if (hos::GetVersion() >= hos::Version_9_0_0) { if (hos::GetVersion() >= hos::Version_900) {
R_ABORT_UNLESS(this->interface->RedirectHtmlDocumentPath(path, id, owner_id)); R_ABORT_UNLESS(this->interface->RedirectHtmlDocumentPath(path, id, owner_id));
} else { } else {
R_ABORT_UNLESS(this->interface->RedirectHtmlDocumentPathDeprecated(path, id)); R_ABORT_UNLESS(this->interface->RedirectHtmlDocumentPathDeprecated(path, id));

View File

@@ -33,7 +33,6 @@
#include <stratosphere/ncm/ncm_install_task_base.hpp> #include <stratosphere/ncm/ncm_install_task_base.hpp>
#include <stratosphere/ncm/ncm_install_task_data.hpp> #include <stratosphere/ncm/ncm_install_task_data.hpp>
#include <stratosphere/ncm/ncm_install_task_occupied_size.hpp> #include <stratosphere/ncm/ncm_install_task_occupied_size.hpp>
#include <stratosphere/ncm/ncm_memory_report.hpp>
#include <stratosphere/ncm/ncm_package_install_task_base.hpp> #include <stratosphere/ncm/ncm_package_install_task_base.hpp>
#include <stratosphere/ncm/ncm_package_install_task.hpp> #include <stratosphere/ncm/ncm_package_install_task.hpp>
#include <stratosphere/ncm/ncm_package_system_update_task.hpp> #include <stratosphere/ncm/ncm_package_system_update_task.hpp>

View File

@@ -27,7 +27,7 @@ namespace ams::ncm {
} }
bool ShouldBuildDatabase() const { bool ShouldBuildDatabase() const {
return hos::GetVersion() < hos::Version_4_0_0 || this->build_system_database; return hos::GetVersion() < hos::Version_400 || this->build_system_database;
} }
bool ShouldImportDatabaseFromSignedSystemPartitionOnSd() const { bool ShouldImportDatabaseFromSignedSystemPartitionOnSd() const {

View File

@@ -30,32 +30,14 @@
namespace ams::ncm { namespace ams::ncm {
class ContentMetaMemoryResource : public MemoryResource { class ContentMetaMemoryResource {
private: private:
mem::StandardAllocator allocator; mem::StandardAllocator allocator;
size_t peak_total_alloc_size; sf::StandardAllocatorMemoryResource memory_resource;
size_t peak_alloc_size;
public: public:
explicit ContentMetaMemoryResource(void *heap, size_t heap_size) : allocator(heap, heap_size) { /* ... */ } ContentMetaMemoryResource(void *heap, size_t heap_size) : allocator(heap, heap_size), memory_resource(std::addressof(allocator)) { /* ... */ }
mem::StandardAllocator *GetAllocator() { return std::addressof(this->allocator); } MemoryResource *Get() { return std::addressof(this->memory_resource); }
size_t GetPeakTotalAllocationSize() const { return this->peak_total_alloc_size; }
size_t GetPeakAllocationSize() const { return this->peak_alloc_size; }
private:
virtual void *AllocateImpl(size_t size, size_t alignment) override {
void *mem = this->allocator.Allocate(size, alignment);
this->peak_total_alloc_size = std::max(this->allocator.Hash().allocated_size, this->peak_total_alloc_size);
this->peak_alloc_size = std::max(size, this->peak_alloc_size);
return mem;
}
virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override {
return this->allocator.Free(buffer);
}
virtual bool IsEqualImpl(const MemoryResource &resource) const override {
return this == std::addressof(resource);
}
}; };
struct SystemSaveDataInfo { struct SystemSaveDataInfo {
@@ -145,7 +127,6 @@ namespace ams::ncm {
virtual Result ActivateContentMetaDatabase(StorageId storage_id) override; virtual Result ActivateContentMetaDatabase(StorageId storage_id) override;
virtual Result InactivateContentMetaDatabase(StorageId storage_id) override; virtual Result InactivateContentMetaDatabase(StorageId storage_id) override;
virtual Result InvalidateRightsIdCache() override; virtual Result InvalidateRightsIdCache() override;
virtual Result GetMemoryReport(sf::Out<MemoryReport> out) override;
}; };
} }

View File

@@ -144,25 +144,25 @@ namespace ams::ncm {
Result GetRightsId(ams::fs::RightsId *out_rights_id, PlaceHolderId placeholder_id) { Result GetRightsId(ams::fs::RightsId *out_rights_id, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_3_0_0); AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_300);
return this->interface->GetRightsIdFromPlaceHolderIdDeprecated(out_rights_id, placeholder_id); return this->interface->GetRightsIdFromPlaceHolderIdDeprecated(out_rights_id, placeholder_id);
} }
Result GetRightsId(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id) { Result GetRightsId(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_3_0_0); AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_300);
return this->interface->GetRightsIdFromPlaceHolderId(out_rights_id, placeholder_id); return this->interface->GetRightsIdFromPlaceHolderId(out_rights_id, placeholder_id);
} }
Result GetRightsId(ams::fs::RightsId *out_rights_id, ContentId content_id) { Result GetRightsId(ams::fs::RightsId *out_rights_id, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_3_0_0); AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_300);
return this->interface->GetRightsIdFromContentIdDeprecated(out_rights_id, content_id); return this->interface->GetRightsIdFromContentIdDeprecated(out_rights_id, content_id);
} }
Result GetRightsId(ncm::RightsId *out_rights_id, ContentId content_id) { Result GetRightsId(ncm::RightsId *out_rights_id, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr); AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_3_0_0); AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_300);
return this->interface->GetRightsIdFromContentId(out_rights_id, content_id); return this->interface->GetRightsIdFromContentId(out_rights_id, content_id);
} }

View File

@@ -16,7 +16,6 @@
#pragma once #pragma once
#include <stratosphere/ncm/ncm_i_content_storage.hpp> #include <stratosphere/ncm/ncm_i_content_storage.hpp>
#include <stratosphere/ncm/ncm_i_content_meta_database.hpp> #include <stratosphere/ncm/ncm_i_content_meta_database.hpp>
#include <stratosphere/ncm/ncm_memory_report.hpp>
namespace ams::ncm { namespace ams::ncm {
@@ -37,7 +36,6 @@ namespace ams::ncm {
ActivateContentMetaDatabase = 11, ActivateContentMetaDatabase = 11,
InactivateContentMetaDatabase = 12, InactivateContentMetaDatabase = 12,
InvalidateRightsIdCache = 13, InvalidateRightsIdCache = 13,
GetMemoryReport = 14,
}; };
public: public:
virtual Result CreateContentStorage(StorageId storage_id) = 0; virtual Result CreateContentStorage(StorageId storage_id) = 0;
@@ -54,7 +52,6 @@ namespace ams::ncm {
virtual Result ActivateContentMetaDatabase(StorageId storage_id) = 0; virtual Result ActivateContentMetaDatabase(StorageId storage_id) = 0;
virtual Result InactivateContentMetaDatabase(StorageId storage_id) = 0; virtual Result InactivateContentMetaDatabase(StorageId storage_id) = 0;
virtual Result InvalidateRightsIdCache() = 0; virtual Result InvalidateRightsIdCache() = 0;
virtual Result GetMemoryReport(sf::Out<MemoryReport> out) = 0;
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(CreateContentStorage), MAKE_SERVICE_COMMAND_META(CreateContentStorage),
@@ -63,15 +60,14 @@ namespace ams::ncm {
MAKE_SERVICE_COMMAND_META(VerifyContentMetaDatabase), MAKE_SERVICE_COMMAND_META(VerifyContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(OpenContentStorage), MAKE_SERVICE_COMMAND_META(OpenContentStorage),
MAKE_SERVICE_COMMAND_META(OpenContentMetaDatabase), MAKE_SERVICE_COMMAND_META(OpenContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(CloseContentStorageForcibly, hos::Version_1_0_0, hos::Version_1_0_0), MAKE_SERVICE_COMMAND_META(CloseContentStorageForcibly, hos::Version_100, hos::Version_100),
MAKE_SERVICE_COMMAND_META(CloseContentMetaDatabaseForcibly, hos::Version_1_0_0, hos::Version_1_0_0), MAKE_SERVICE_COMMAND_META(CloseContentMetaDatabaseForcibly, hos::Version_100, hos::Version_100),
MAKE_SERVICE_COMMAND_META(CleanupContentMetaDatabase), MAKE_SERVICE_COMMAND_META(CleanupContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(ActivateContentStorage, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(ActivateContentStorage, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InactivateContentStorage, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(InactivateContentStorage, hos::Version_200),
MAKE_SERVICE_COMMAND_META(ActivateContentMetaDatabase, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(ActivateContentMetaDatabase, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InactivateContentMetaDatabase, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(InactivateContentMetaDatabase, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InvalidateRightsIdCache, hos::Version_9_0_0), MAKE_SERVICE_COMMAND_META(InvalidateRightsIdCache, hos::Version_900),
MAKE_SERVICE_COMMAND_META(GetMemoryReport, hos::Version_10_0_0),
}; };
}; };

View File

@@ -43,8 +43,6 @@ namespace ams::ncm {
GetAttributes = 18, GetAttributes = 18,
GetRequiredApplicationVersion = 19, GetRequiredApplicationVersion = 19,
GetContentIdByTypeAndIdOffset = 20, GetContentIdByTypeAndIdOffset = 20,
GetCount = 21,
GetOwnerApplicationId = 22,
}; };
public: public:
/* Actual commands. */ /* Actual commands. */
@@ -69,8 +67,6 @@ namespace ams::ncm {
virtual Result GetAttributes(sf::Out<u8> out_attributes, const ContentMetaKey &key) = 0; virtual Result GetAttributes(sf::Out<u8> out_attributes, const ContentMetaKey &key) = 0;
virtual Result GetRequiredApplicationVersion(sf::Out<u32> out_version, const ContentMetaKey &key) = 0; virtual Result GetRequiredApplicationVersion(sf::Out<u32> out_version, const ContentMetaKey &key) = 0;
virtual Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0; virtual Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0;
virtual Result GetCount(sf::Out<u32> out_count) = 0;
virtual Result GetOwnerApplicationId(sf::Out<ApplicationId> out_id, const ContentMetaKey &key) = 0;
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(Set), MAKE_SERVICE_COMMAND_META(Set),
@@ -92,10 +88,8 @@ namespace ams::ncm {
MAKE_SERVICE_COMMAND_META(HasContent), MAKE_SERVICE_COMMAND_META(HasContent),
MAKE_SERVICE_COMMAND_META(ListContentMetaInfo), MAKE_SERVICE_COMMAND_META(ListContentMetaInfo),
MAKE_SERVICE_COMMAND_META(GetAttributes), MAKE_SERVICE_COMMAND_META(GetAttributes),
MAKE_SERVICE_COMMAND_META(GetRequiredApplicationVersion, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(GetRequiredApplicationVersion, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetContentIdByTypeAndIdOffset, hos::Version_5_0_0), MAKE_SERVICE_COMMAND_META(GetContentIdByTypeAndIdOffset, hos::Version_500),
MAKE_SERVICE_COMMAND_META(GetCount, hos::Version_10_0_0),
MAKE_SERVICE_COMMAND_META(GetOwnerApplicationId, hos::Version_10_0_0),
}; };
}; };

View File

@@ -110,20 +110,20 @@ namespace ams::ncm {
MAKE_SERVICE_COMMAND_META(ListContentId), MAKE_SERVICE_COMMAND_META(ListContentId),
MAKE_SERVICE_COMMAND_META(GetSizeFromContentId), MAKE_SERVICE_COMMAND_META(GetSizeFromContentId),
MAKE_SERVICE_COMMAND_META(DisableForcibly), MAKE_SERVICE_COMMAND_META(DisableForcibly),
MAKE_SERVICE_COMMAND_META(RevertToPlaceHolder, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(RevertToPlaceHolder, hos::Version_200),
MAKE_SERVICE_COMMAND_META(SetPlaceHolderSize, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(SetPlaceHolderSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(ReadContentIdFile, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(ReadContentIdFile, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdDeprecated, hos::Version_2_0_0, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdDeprecated, hos::Version_200, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderId, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderId, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentIdDeprecated, hos::Version_2_0_0, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentIdDeprecated, hos::Version_200, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentId, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentId, hos::Version_300),
MAKE_SERVICE_COMMAND_META(WriteContentForDebug, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(WriteContentForDebug, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize, hos::Version_2_0_0), MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(FlushPlaceHolder, hos::Version_3_0_0), MAKE_SERVICE_COMMAND_META(FlushPlaceHolder, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetSizeFromPlaceHolderId, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(GetSizeFromPlaceHolderId, hos::Version_400),
MAKE_SERVICE_COMMAND_META(RepairInvalidFileAttribute, hos::Version_4_0_0), MAKE_SERVICE_COMMAND_META(RepairInvalidFileAttribute, hos::Version_400),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdWithCache, hos::Version_8_0_0), MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdWithCache, hos::Version_800),
}; };
}; };

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 2019-2020 Adubbz, 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/os.hpp>
#include <stratosphere/lmem/lmem_common.hpp>
namespace ams::ncm {
struct MemoryResourceState {
size_t peak_total_alloc_size;
size_t peak_alloc_size;
size_t allocatable_size;
size_t total_free_size;
};
static_assert(sizeof(MemoryResourceState) == 0x20);
struct MemoryReport {
MemoryResourceState system_content_meta_resource_state;
MemoryResourceState sd_and_user_content_meta_resource_state;
MemoryResourceState gamecard_content_meta_resource_state;
MemoryResourceState heap_resource_state;
};
static_assert(sizeof(MemoryReport) == 0x80);
class HeapState {
private:
os::Mutex mutex;
lmem::HeapHandle heap_handle;
size_t total_alloc_size;
size_t peak_total_alloc_size;
size_t peak_alloc_size;
public:
constexpr HeapState() : mutex(false), heap_handle(nullptr), total_alloc_size(0), peak_total_alloc_size(0), peak_alloc_size(0) { /* ... */ }
void Initialize(lmem::HeapHandle heap_handle);
void Allocate(size_t size);
void Free(size_t size);
void GetMemoryResourceState(MemoryResourceState *out);
};
HeapState &GetHeapState();
}

View File

@@ -95,7 +95,6 @@ namespace ams::ncm {
static const SystemProgramId Dt; static const SystemProgramId Dt;
static const SystemProgramId Nd; static const SystemProgramId Nd;
static const SystemProgramId Ngct; static const SystemProgramId Ngct;
static const SystemProgramId Pgl;
static const SystemProgramId End; static const SystemProgramId End;
}; };
@@ -193,7 +192,6 @@ namespace ams::ncm {
inline constexpr const SystemProgramId SystemProgramId::Dt = { 0x010000000000003Ful }; inline constexpr const SystemProgramId SystemProgramId::Dt = { 0x010000000000003Ful };
inline constexpr const SystemProgramId SystemProgramId::Nd = { 0x0100000000000040ul }; inline constexpr const SystemProgramId SystemProgramId::Nd = { 0x0100000000000040ul };
inline constexpr const SystemProgramId SystemProgramId::Ngct = { 0x0100000000000041ul }; inline constexpr const SystemProgramId SystemProgramId::Ngct = { 0x0100000000000041ul };
inline constexpr const SystemProgramId SystemProgramId::Pgl = { 0x0100000000000042ul };
inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul }; inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul };
@@ -402,34 +400,6 @@ namespace ams::ncm {
return true; return true;
} }
struct SystemDebugAppletId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
static const SystemDebugAppletId Start;
static const SystemDebugAppletId SnapShotDumper;
static const SystemDebugAppletId End;
};
inline constexpr const SystemDebugAppletId SystemDebugAppletId::Start = { 0x0100000000002000ul };
inline constexpr const SystemDebugAppletId SystemDebugAppletId::SnapShotDumper = { 0x0100000000002071ul };
inline constexpr const SystemDebugAppletId SystemDebugAppletId::End = { 0x0100000000002FFFul };
inline constexpr bool IsSystemDebugAppletId(const ProgramId &program_id) {
return SystemDebugAppletId::Start <= program_id && program_id <= SystemDebugAppletId::End;
}
inline constexpr bool IsSystemDebugAppletId(const SystemDebugAppletId &program_id) {
return true;
}
struct LibraryAppletId { struct LibraryAppletId {
u64 value; u64 value;

View File

@@ -27,7 +27,6 @@
#include <stratosphere/os/os_random.hpp> #include <stratosphere/os/os_random.hpp>
#include <stratosphere/os/os_mutex.hpp> #include <stratosphere/os/os_mutex.hpp>
#include <stratosphere/os/os_condition_variable.hpp> #include <stratosphere/os/os_condition_variable.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/os/os_rw_lock.hpp> #include <stratosphere/os/os_rw_lock.hpp>
#include <stratosphere/os/os_semaphore.hpp> #include <stratosphere/os/os_semaphore.hpp>
#include <stratosphere/os/os_event.hpp> #include <stratosphere/os/os_event.hpp>

View File

@@ -1,60 +0,0 @@
/*
* 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/os/impl/os_internal_critical_section.hpp>
namespace ams::os {
class SdkConditionVariable;
struct SdkMutexType {
union {
s32 _arr[sizeof(impl::InternalCriticalSectionStorage) / sizeof(s32)];
impl::InternalCriticalSectionStorage _storage;
};
};
static_assert(std::is_trivial<SdkMutexType>::value);
void InitializeSdkMutex(SdkMutexType *mutex);
void LockSdkMutex(SdkMutexType *mutex);
bool TryLockSdkMutex(SdkMutexType *mutex);
void UnlockSdkMutex(SdkMutexType *mutex);
bool IsSdkMutexLockedByCurrentThread(const SdkMutexType *mutex);
class SdkMutex {
private:
friend class SdkConditionVariable;
private:
SdkMutexType mutex;
public:
constexpr SdkMutex() : mutex{{0}} { /* ... */ }
ALWAYS_INLINE void Lock() { return os::LockSdkMutex(std::addressof(this->mutex)); }
ALWAYS_INLINE bool TryLock() { return os::TryLockSdkMutex(std::addressof(this->mutex)); }
ALWAYS_INLINE void Unlock() { return os::UnlockSdkMutex(std::addressof(this->mutex)); }
ALWAYS_INLINE bool IsLockedByCurrentThread() const { return os::IsSdkMutexLockedByCurrentThread(std::addressof(this->mutex)); }
ALWAYS_INLINE void lock() { return this->Lock(); }
ALWAYS_INLINE bool try_lock() { return this->TryLock(); }
ALWAYS_INLINE void unlock() { return this->Unlock(); }
};
}

View File

@@ -1,23 +0,0 @@
/*
* 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 <stratosphere/pgl/pgl_types.hpp>
#include <stratosphere/pgl/pgl_event_observer.hpp>
#include <stratosphere/pgl/pgl_shell_api.hpp>
#include <stratosphere/pgl/pgl_shell_api.hpp>
#include <stratosphere/pgl/srv/pgl_srv_api.hpp>

View File

@@ -1,58 +0,0 @@
/*
* Copyright (c) 2019-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 <stratosphere/os.hpp>
#include <stratosphere/pm.hpp>
#include <stratosphere/pgl/pgl_types.hpp>
#include <stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp>
namespace ams::pgl {
class EventObserver {
NON_COPYABLE(EventObserver);
private:
std::shared_ptr<pgl::sf::IEventObserver> interface;
public:
EventObserver() { /* ... */ }
explicit EventObserver(std::shared_ptr<pgl::sf::IEventObserver> intf) : interface(std::move(intf)) { /* ... */ }
EventObserver(EventObserver &&rhs) {
this->interface = std::move(rhs.interface);
}
EventObserver &operator=(EventObserver &&rhs) {
EventObserver(std::move(rhs)).Swap(*this);
return *this;
}
void Swap(EventObserver &rhs) {
std::swap(this->interface, rhs.interface);
}
public:
Result GetSystemEvent(os::SystemEventType *out) {
ams::sf::CopyHandle handle;
R_TRY(this->interface->GetProcessEventHandle(std::addressof(handle)));
os::AttachSystemEvent(out, handle.GetValue(), true, svc::InvalidHandle, false, os::EventClearMode_AutoClear);
return ResultSuccess();
}
Result GetProcessEventInfo(pm::ProcessEventInfo *out) {
return this->interface->GetProcessEventInfo(out);
}
};
}

View File

@@ -1,41 +0,0 @@
/*
* 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/pgl/pgl_types.hpp>
#include <stratosphere/pgl/pgl_event_observer.hpp>
namespace ams::pgl {
Result Initialize();
void Finalize();
Result LaunchProgram(os::ProcessId *out, const ncm::ProgramLocation &loc, u32 process_flags, u8 pgl_flags);
Result TerminateProcess(os::ProcessId process_id);
Result LaunchProgramFromHost(os::ProcessId *out, const char *content_path, u32 process_flags);
Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *content_path);
Result GetApplicationProcessId(os::ProcessId *out);
Result BoostSystemMemoryResourceLimit(u64 size);
Result IsProcessTracked(bool *out, os::ProcessId process_id);
Result EnableApplicationCrashReport(bool enabled);
Result IsApplicationCrashReportEnabled(bool *out);
Result EnableApplicationAllThreadDumpOnCrash(bool enabled);
Result TriggerApplicationSnapShotDumper(const char *arg, SnapShotDumpType dump_type);
Result GetEventObserver(pgl::EventObserver *out);
}

View File

@@ -1,57 +0,0 @@
/*
* 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/os.hpp>
#include <stratosphere/pm.hpp>
#include <stratosphere/ncm.hpp>
namespace ams::pgl {
enum LaunchFlags : u8 {
LaunchFlags_None = 0,
LaunchFlags_EnableDetailedCrashReport = (1 << 0),
LaunchFlags_EnableCrashReportScreenShotForProduction = (1 << 1),
LaunchFlags_EnableCrashReportScreenShotForDevelop = (1 << 2),
};
enum class SnapShotDumpType : u32 {
None = 0,
Auto = 1,
Full = 2,
};
/* TODO: Is this really nn::ncm::Content<Something>Info? */
struct ContentMetaInfo {
u64 id;
u32 version;
ncm::ContentType content_type;
u8 id_offset;
u8 reserved_0E[2];
static constexpr ContentMetaInfo Make(u64 id, u32 version, ncm::ContentType content_type, u8 id_offset) {
return {
.id = id,
.version = version,
.content_type = content_type,
.id_offset = id_offset,
};
}
};
static_assert(sizeof(ContentMetaInfo) == 0x10 && std::is_pod<ContentMetaInfo>::value);
}

View File

@@ -1,42 +0,0 @@
/*
* 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/os.hpp>
#include <stratosphere/pm.hpp>
#include <stratosphere/pgl/pgl_types.hpp>
namespace ams::pgl::sf {
class IEventObserver : public ams::sf::IServiceObject {
protected:
enum class CommandId {
GetProcessEventHandle = 0,
GetProcessEventInfo = 1,
};
public:
/* Actual commands. */
virtual Result GetProcessEventHandle(ams::sf::OutCopyHandle out) = 0;
virtual Result GetProcessEventInfo(ams::sf::Out<pm::ProcessEventInfo> out) = 0;
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(GetProcessEventHandle),
MAKE_SERVICE_COMMAND_META(GetProcessEventInfo),
};
};
}

View File

@@ -1,74 +0,0 @@
/*
* 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/os.hpp>
#include <stratosphere/pm.hpp>
#include <stratosphere/pgl/pgl_types.hpp>
#include <stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp>
namespace ams::pgl::sf {
class IShellInterface : public ams::sf::IServiceObject {
protected:
enum class CommandId {
LaunchProgram = 0,
TerminateProcess = 1,
LaunchProgramFromHost = 2,
GetHostContentMetaInfo = 4,
GetApplicationProcessId = 5,
BoostSystemMemoryResourceLimit = 6,
IsProcessTracked = 7,
EnableApplicationCrashReport = 8,
IsApplicationCrashReportEnabled = 9,
EnableApplicationAllThreadDumpOnCrash = 10,
TriggerApplicationSnapShotDumper = 12,
GetShellEventObserver = 20,
};
public:
/* Actual commands. */
virtual Result LaunchProgram(ams::sf::Out<os::ProcessId> out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) = 0;
virtual Result TerminateProcess(os::ProcessId process_id) = 0;
virtual Result LaunchProgramFromHost(ams::sf::Out<os::ProcessId> out, const ams::sf::InBuffer &content_path, u32 pm_flags) = 0;
virtual Result GetHostContentMetaInfo(ams::sf::Out<pgl::ContentMetaInfo> out, const ams::sf::InBuffer &content_path) = 0;
virtual Result GetApplicationProcessId(ams::sf::Out<os::ProcessId> out) = 0;
virtual Result BoostSystemMemoryResourceLimit(u64 size) = 0;
virtual Result IsProcessTracked(ams::sf::Out<bool> out, os::ProcessId process_id) = 0;
virtual Result EnableApplicationCrashReport(bool enabled) = 0;
virtual Result IsApplicationCrashReportEnabled(ams::sf::Out<bool> out) = 0;
virtual Result EnableApplicationAllThreadDumpOnCrash(bool enabled) = 0;
virtual Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg) = 0;
virtual Result GetShellEventObserver(ams::sf::Out<std::shared_ptr<pgl::sf::IEventObserver>> out) = 0;
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(LaunchProgram),
MAKE_SERVICE_COMMAND_META(TerminateProcess),
MAKE_SERVICE_COMMAND_META(LaunchProgramFromHost),
MAKE_SERVICE_COMMAND_META(GetHostContentMetaInfo),
MAKE_SERVICE_COMMAND_META(GetApplicationProcessId),
MAKE_SERVICE_COMMAND_META(BoostSystemMemoryResourceLimit),
MAKE_SERVICE_COMMAND_META(IsProcessTracked),
MAKE_SERVICE_COMMAND_META(EnableApplicationCrashReport),
MAKE_SERVICE_COMMAND_META(IsApplicationCrashReportEnabled),
MAKE_SERVICE_COMMAND_META(EnableApplicationAllThreadDumpOnCrash),
MAKE_SERVICE_COMMAND_META(TriggerApplicationSnapShotDumper),
MAKE_SERVICE_COMMAND_META(GetShellEventObserver),
};
};
}

View File

@@ -1,25 +0,0 @@
/*
* 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/pgl/pgl_types.hpp>
#include <stratosphere/pgl/srv/pgl_srv_shell_interface.hpp>
namespace ams::pgl::srv {
void Initialize(ShellInterface *interface, MemoryResource *mr);
}

View File

@@ -1,52 +0,0 @@
/*
* 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/pgl/pgl_types.hpp>
#include <stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp>
namespace ams::pgl::srv {
class ShellInterface final : public pgl::sf::IShellInterface {
NON_COPYABLE(ShellInterface);
NON_MOVEABLE(ShellInterface);
private:
MemoryResource *memory_resource;
public:
constexpr ShellInterface() : memory_resource(nullptr) { /* ... */ }
void Initialize(MemoryResource *mr) {
AMS_ASSERT(this->memory_resource == nullptr);
this->memory_resource = mr;
}
public:
/* Interface commands. */
virtual Result LaunchProgram(ams::sf::Out<os::ProcessId> out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) override final;
virtual Result TerminateProcess(os::ProcessId process_id) override final;
virtual Result LaunchProgramFromHost(ams::sf::Out<os::ProcessId> out, const ams::sf::InBuffer &content_path, u32 pm_flags) override final;
virtual Result GetHostContentMetaInfo(ams::sf::Out<pgl::ContentMetaInfo> out, const ams::sf::InBuffer &content_path) override final;
virtual Result GetApplicationProcessId(ams::sf::Out<os::ProcessId> out) override final;
virtual Result BoostSystemMemoryResourceLimit(u64 size) override final;
virtual Result IsProcessTracked(ams::sf::Out<bool> out, os::ProcessId process_id) override final;
virtual Result EnableApplicationCrashReport(bool enabled) override final;
virtual Result IsApplicationCrashReportEnabled(ams::sf::Out<bool> out) override final;
virtual Result EnableApplicationAllThreadDumpOnCrash(bool enabled) override final;
virtual Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg) override final;
virtual Result GetShellEventObserver(ams::sf::Out<std::shared_ptr<pgl::sf::IEventObserver>> out) override final;
};
}

View File

@@ -23,12 +23,6 @@
namespace ams::pm::shell { namespace ams::pm::shell {
/* Shell API. */ /* Shell API. */
Result LaunchProgram(os::ProcessId *out, const ncm::ProgramLocation &loc, u32 launch_flags); Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags);
Result TerminateProcess(os::ProcessId process_id);
Result GetProcessEventEvent(os::SystemEvent *out);
Result GetProcessEventInfo(ProcessEventInfo *out);
Result GetApplicationProcessIdForShell(os::ProcessId *out);
Result BoostSystemMemoryResourceLimit(u64 size);
Result EnableApplicationExtraThread();
} }

View File

@@ -32,66 +32,7 @@ namespace ams::pm {
ResourceLimitGroup_Count, ResourceLimitGroup_Count,
}; };
enum LaunchFlags : u32 { using LimitableResource = ::LimitableResource;
LaunchFlags_None = 0,
LaunchFlags_SignalOnExit = (1 << 0),
LaunchFlags_SignalOnStart = (1 << 1),
LaunchFlags_SignalOnException = (1 << 2),
LaunchFlags_SignalOnDebugEvent = (1 << 3),
LaunchFlags_StartSuspended = (1 << 4),
LaunchFlags_DisableAslr = (1 << 5),
};
enum LaunchFlagsDeprecated : u32 {
LaunchFlagsDeprecated_None = 0,
LaunchFlagsDeprecated_SignalOnExit = (1 << 0),
LaunchFlagsDeprecated_StartSuspended = (1 << 1),
LaunchFlagsDeprecated_SignalOnException = (1 << 2),
LaunchFlagsDeprecated_DisableAslr = (1 << 3),
LaunchFlagsDeprecated_SignalOnDebugEvent = (1 << 4),
LaunchFlagsDeprecated_SignalOnStart = (1 << 5),
};
constexpr inline u32 LaunchFlagsMask = (1 << 6) - 1;
enum class ProcessEvent : u32 {
None = 0,
Exited = 1,
Started = 2,
Exception = 3,
DebugRunning = 4,
DebugBreak = 5,
};
enum class ProcessEventDeprecated : u32 {
None = 0,
Exception = 1,
Exited = 2,
DebugRunning = 3,
DebugBreak = 4,
Started = 5,
};
inline u32 GetProcessEventValue(ProcessEvent event) {
if (hos::GetVersion() >= hos::Version_5_0_0) {
return static_cast<u32>(event);
}
switch (event) {
case ProcessEvent::None:
return static_cast<u32>(ProcessEventDeprecated::None);
case ProcessEvent::Exited:
return static_cast<u32>(ProcessEventDeprecated::Exited);
case ProcessEvent::Started:
return static_cast<u32>(ProcessEventDeprecated::Started);
case ProcessEvent::Exception:
return static_cast<u32>(ProcessEventDeprecated::Exception);
case ProcessEvent::DebugRunning:
return static_cast<u32>(ProcessEventDeprecated::DebugRunning);
case ProcessEvent::DebugBreak:
return static_cast<u32>(ProcessEventDeprecated::DebugBreak);
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
struct ProcessEventInfo { struct ProcessEventInfo {
u32 event; u32 event;

View File

@@ -43,7 +43,7 @@ namespace ams::psc::sf {
MAKE_SERVICE_COMMAND_META(GetRequest), MAKE_SERVICE_COMMAND_META(GetRequest),
MAKE_SERVICE_COMMAND_META(Acknowledge), MAKE_SERVICE_COMMAND_META(Acknowledge),
MAKE_SERVICE_COMMAND_META(Finalize), MAKE_SERVICE_COMMAND_META(Finalize),
MAKE_SERVICE_COMMAND_META(AcknowledgeEx, hos::Version_6_0_0), /* TODO: This is really 5.1.0... */ MAKE_SERVICE_COMMAND_META(AcknowledgeEx, hos::Version_600), /* TODO: This is really 5.1.0... */
}; };
}; };

View File

@@ -19,7 +19,6 @@
#include "settings/settings_types.hpp" #include "settings/settings_types.hpp"
#include "settings/settings_fwdbg_types.hpp" #include "settings/settings_fwdbg_types.hpp"
#include "settings/settings_fwdbg_api.hpp" #include "settings/settings_fwdbg_api.hpp"
#include "settings/system/settings_error_report.hpp"
#include "settings/system/settings_firmware_version.hpp" #include "settings/system/settings_firmware_version.hpp"
#include "settings/system/settings_product_model.hpp" #include "settings/system/settings_product_model.hpp"
#include "settings/system/settings_region.hpp" #include "settings/system/settings_region.hpp"

View File

@@ -1,31 +0,0 @@
/*
* 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/settings/settings_types.hpp>
namespace ams::settings::system {
enum ErrorReportSharePermission {
ErrorReportSharePermission_NotConfirmed = 0,
ErrorReportSharePermission_Granted = 1,
ErrorReportSharePermission_Denied = 2,
};
ErrorReportSharePermission GetErrorReportSharePermission();
}

View File

@@ -16,16 +16,15 @@
#pragma once #pragma once
#include <stratosphere/sf/sf_common.hpp> #include "sf/sf_common.hpp"
#include <stratosphere/sf/sf_lmem_utility.hpp> #include "sf/sf_mem_utility.hpp"
#include <stratosphere/sf/sf_mem_utility.hpp> #include "sf/sf_service_object.hpp"
#include <stratosphere/sf/sf_service_object.hpp> #include "sf/hipc/sf_hipc_server_session_manager.hpp"
#include <stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp>
#include <stratosphere/sf/sf_out.hpp> #include "sf/sf_out.hpp"
#include <stratosphere/sf/sf_buffers.hpp> #include "sf/sf_buffers.hpp"
#include <stratosphere/sf/impl/sf_impl_command_serialization.hpp> #include "sf/impl/sf_impl_command_serialization.hpp"
#include <stratosphere/sf/hipc/sf_hipc_server_manager.hpp> #include "sf/hipc/sf_hipc_server_manager.hpp"
#include <stratosphere/sf/sf_mitm_dispatch.h> #include "sf/sf_mitm_dispatch.h"

View File

@@ -1,67 +0,0 @@
/*
* 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 <stratosphere/sf/sf_common.hpp>
#include <stratosphere/lmem.hpp>
namespace ams::sf {
class ExpHeapMemoryResource : public MemoryResource {
private:
lmem::HeapHandle handle;
public:
explicit ExpHeapMemoryResource(lmem::HeapHandle h) : handle(h) { /* ... */ }
lmem::HeapHandle GetHandle() const { return this->handle; }
private:
virtual void *AllocateImpl(size_t size, size_t alignment) override {
return lmem::AllocateFromExpHeap(this->handle, size, static_cast<int>(alignment));
}
virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override {
return lmem::FreeToExpHeap(this->handle, buffer);
}
virtual bool IsEqualImpl(const MemoryResource &resource) const {
return this == std::addressof(resource);
}
};
class UnitHeapMemoryResource : public MemoryResource {
private:
lmem::HeapHandle handle;
public:
explicit UnitHeapMemoryResource(lmem::HeapHandle h) : handle(h) { /* ... */ }
lmem::HeapHandle GetHandle() const { return this->handle; }
private:
virtual void *AllocateImpl(size_t size, size_t alignment) override {
AMS_ASSERT(size <= lmem::GetUnitHeapUnitSize(this->handle));
AMS_ASSERT(alignment <= static_cast<size_t>(lmem::GetUnitHeapAlignment(this->handle)));
return lmem::AllocateFromUnitHeap(this->handle);
}
virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override {
return lmem::FreeToUnitHeap(this->handle, buffer);
}
virtual bool IsEqualImpl(const MemoryResource &resource) const {
return this == std::addressof(resource);
}
};
}

View File

@@ -21,7 +21,6 @@ namespace ams::spl {
HardwareType GetHardwareType(); HardwareType GetHardwareType();
MemoryArrangement GetMemoryArrangement(); MemoryArrangement GetMemoryArrangement();
bool IsDisabledProgramVerification();
bool IsDevelopmentHardware(); bool IsDevelopmentHardware();
bool IsDevelopmentFunctionEnabled(); bool IsDevelopmentFunctionEnabled();
bool IsMariko(); bool IsMariko();

View File

@@ -318,12 +318,8 @@ namespace ams::svc::aarch64::lp64 {
return ::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address); return ::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address);
} }
ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) {
return ::svcQueryIoMapping(reinterpret_cast<u64 *>(out_address), reinterpret_cast<u64 *>(out_size), physical_address, size); return ::svcQueryIoMapping(reinterpret_cast<u64 *>(out_address), physical_address, size);
}
ALWAYS_INLINE Result LegacyQueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) {
return ::svcLegacyQueryIoMapping(reinterpret_cast<u64 *>(out_address), physical_address, size);
} }
ALWAYS_INLINE Result CreateDeviceAddressSpace(::ams::svc::Handle *out_handle, uint64_t das_address, uint64_t das_size) { ALWAYS_INLINE Result CreateDeviceAddressSpace(::ams::svc::Handle *out_handle, uint64_t das_address, uint64_t das_size) {

View File

@@ -39,7 +39,6 @@ namespace ams::boot2 {
ncm::SystemProgramId::NvServices, /* nvservices */ ncm::SystemProgramId::NvServices, /* nvservices */
ncm::SystemProgramId::NvnFlinger, /* nvnflinger */ ncm::SystemProgramId::NvnFlinger, /* nvnflinger */
ncm::SystemProgramId::Vi, /* vi */ ncm::SystemProgramId::Vi, /* vi */
ncm::SystemProgramId::Pgl, /* pgl */
ncm::SystemProgramId::Ns, /* ns */ ncm::SystemProgramId::Ns, /* ns */
ncm::SystemProgramId::LogManager, /* lm */ ncm::SystemProgramId::LogManager, /* lm */
ncm::SystemProgramId::Ppc, /* ppc */ ncm::SystemProgramId::Ppc, /* ppc */
@@ -85,7 +84,6 @@ namespace ams::boot2 {
ncm::SystemProgramId::NvServices, /* nvservices */ ncm::SystemProgramId::NvServices, /* nvservices */
ncm::SystemProgramId::NvnFlinger, /* nvnflinger */ ncm::SystemProgramId::NvnFlinger, /* nvnflinger */
ncm::SystemProgramId::Vi, /* vi */ ncm::SystemProgramId::Vi, /* vi */
ncm::SystemProgramId::Pgl, /* pgl */
ncm::SystemProgramId::Ns, /* ns */ ncm::SystemProgramId::Ns, /* ns */
ncm::SystemProgramId::LogManager, /* lm */ ncm::SystemProgramId::LogManager, /* lm */
ncm::SystemProgramId::Ppc, /* ppc */ ncm::SystemProgramId::Ppc, /* ppc */
@@ -135,29 +133,19 @@ namespace ams::boot2 {
return c == '\r' || c == '\n'; return c == '\r' || c == '\n';
} }
inline bool IsAllowedLaunchProgram(const ncm::ProgramLocation &loc) {
if (loc.program_id == ncm::SystemProgramId::Pgl) {
return hos::GetVersion() >= hos::Version_10_0_0;
}
return true;
}
void LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) { void LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) {
os::ProcessId process_id = os::InvalidProcessId; os::ProcessId process_id = os::InvalidProcessId;
/* Only launch the process if we're allowed to. */ /* Launch, lightly validate result. */
if (IsAllowedLaunchProgram(loc)) { {
/* Launch, lightly validate result. */ const auto launch_result = pm::shell::LaunchProgram(&process_id, loc, launch_flags);
{ AMS_ABORT_UNLESS(!(svc::ResultOutOfResource::Includes(launch_result)));
const auto launch_result = pm::shell::LaunchProgram(&process_id, loc, launch_flags); AMS_ABORT_UNLESS(!(svc::ResultOutOfMemory::Includes(launch_result)));
AMS_ABORT_UNLESS(!(svc::ResultOutOfResource::Includes(launch_result))); AMS_ABORT_UNLESS(!(svc::ResultLimitReached::Includes(launch_result)));
AMS_ABORT_UNLESS(!(svc::ResultOutOfMemory::Includes(launch_result))); }
AMS_ABORT_UNLESS(!(svc::ResultLimitReached::Includes(launch_result)));
}
if (out_process_id) { if (out_process_id) {
*out_process_id = process_id; *out_process_id = process_id;
}
} }
} }
@@ -320,7 +308,7 @@ namespace ams::boot2 {
/* Wait for other atmosphere mitm modules to initialize. */ /* Wait for other atmosphere mitm modules to initialize. */
R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys"))); R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys")));
if (hos::GetVersion() >= hos::Version_2_0_0) { if (hos::GetVersion() >= hos::Version_200) {
R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc"))); R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc")));
} else { } else {
R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c"))); R_ABORT_UNLESS(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c")));
@@ -349,7 +337,7 @@ namespace ams::boot2 {
if (maintenance) { if (maintenance) {
LaunchList(AdditionalMaintenanceLaunchPrograms, NumAdditionalMaintenanceLaunchPrograms); LaunchList(AdditionalMaintenanceLaunchPrograms, NumAdditionalMaintenanceLaunchPrograms);
/* Starting in 7.0.0, npns is launched during maintenance boot. */ /* Starting in 7.0.0, npns is launched during maintenance boot. */
if (hos::GetVersion() >= hos::Version_7_0_0) { if (hos::GetVersion() >= hos::Version_700) {
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Npns, ncm::StorageId::BuiltInSystem), 0); LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Npns, ncm::StorageId::BuiltInSystem), 0);
} }
} else { } else {

View File

@@ -33,11 +33,11 @@ namespace ams::cfg {
/* SD card helpers. */ /* SD card helpers. */
void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) { void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) {
os::ProcessId min = os::InvalidProcessId, max = os::InvalidProcessId; os::ProcessId min = os::InvalidProcessId, max = os::InvalidProcessId;
if (hos::GetVersion() >= hos::Version_5_0_0) { if (hos::GetVersion() >= hos::Version_500) {
/* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */ /* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */
R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&min), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum)); R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&min), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&max), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum)); R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&max), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
} else if (hos::GetVersion() >= hos::Version_4_0_0) { } else if (hos::GetVersion() >= hos::Version_400) {
/* On 4.0.0-4.1.0, we can get the precise limits from normal svcGetInfo. */ /* On 4.0.0-4.1.0, we can get the precise limits from normal svcGetInfo. */
R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&min), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum)); R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&min), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&max), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum)); R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&max), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));

View File

@@ -22,19 +22,10 @@ namespace ams::dd {
const u64 aligned_addr = util::AlignDown(phys_addr, os::MemoryPageSize); const u64 aligned_addr = util::AlignDown(phys_addr, os::MemoryPageSize);
const size_t offset = phys_addr - aligned_addr; const size_t offset = phys_addr - aligned_addr;
const u64 aligned_size = size + offset; const u64 aligned_size = size + offset;
if (hos::GetVersion() >= hos::Version_10_0_0) { R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) {
u64 region_size; /* Official software handles this by returning 0. */
R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, &region_size, aligned_addr, aligned_size)) { R_CATCH(svc::ResultNotFound) { return 0; }
/* Official software handles this by returning 0. */ } R_END_TRY_CATCH_WITH_ABORT_UNLESS;
R_CATCH(svc::ResultNotFound) { return 0; }
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
AMS_ASSERT(region_size >= aligned_size);
} else {
R_TRY_CATCH(svcLegacyQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) {
/* Official software handles this by returning 0. */
R_CATCH(svc::ResultNotFound) { return 0; }
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
}
return static_cast<uintptr_t>(virtual_addr + offset); return static_cast<uintptr_t>(virtual_addr + offset);
} }

View File

@@ -44,7 +44,7 @@ namespace ams::diag {
inline void DebugLog(const char *format, ...) __attribute__((format(printf, 1, 2))); inline void DebugLog(const char *format, ...) __attribute__((format(printf, 1, 2)));
#ifdef AMS_ENABLE_DEBUG_PRINT #ifdef AMS_ENABLE_DEBUG_PRINT
os::Mutex g_debug_log_lock(true); os::Mutex g_debug_log_lock;
char g_debug_buffer[0x400]; char g_debug_buffer[0x400];
void DebugLogImpl(const char *format, ::std::va_list vl) { void DebugLogImpl(const char *format, ::std::va_list vl) {

View File

@@ -40,7 +40,7 @@ namespace ams::erpt::srv {
R_TRY(fs::GetSaveDataAvailableSize(std::addressof(cur_savedata_size), SystemSaveDataId)); R_TRY(fs::GetSaveDataAvailableSize(std::addressof(cur_savedata_size), SystemSaveDataId));
if (cur_journal_size < SystemSaveDataJournalSize || cur_savedata_size < SystemSaveDataSize) { if (cur_journal_size < SystemSaveDataJournalSize || cur_savedata_size < SystemSaveDataSize) {
if (hos::GetVersion() >= hos::Version_3_0_0) { if (hos::GetVersion() >= hos::Version_300) {
R_TRY(fs::ExtendSaveData(fs::SaveDataSpaceId::System, SystemSaveDataId, SystemSaveDataSize, SystemSaveDataJournalSize)); R_TRY(fs::ExtendSaveData(fs::SaveDataSpaceId::System, SystemSaveDataId, SystemSaveDataSize, SystemSaveDataJournalSize));
} }
} }

View File

@@ -67,7 +67,7 @@ namespace ams::erpt::srv {
Result Reporter::CollectUniqueReportFields() { Result Reporter::CollectUniqueReportFields() {
this->occurrence_tick = os::GetSystemTick(); this->occurrence_tick = os::GetSystemTick();
if (hos::GetVersion() >= hos::Version_3_0_0) { if (hos::GetVersion() >= hos::Version_300) {
this->steady_clock_internal_offset_seconds = time::GetStandardSteadyClockInternalOffset().GetSeconds(); this->steady_clock_internal_offset_seconds = time::GetStandardSteadyClockInternalOffset().GetSeconds();
} else { } else {
this->steady_clock_internal_offset_seconds = 0; this->steady_clock_internal_offset_seconds = 0;

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