Compare commits
3 Commits
dmnt_new_f
...
nim
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8696bd5d4 | ||
|
|
af7baa6b34 | ||
|
|
6de1361c8b |
3
Makefile
3
Makefile
@@ -58,7 +58,6 @@ dist-no-debug: all
|
||||
mkdir atmosphere-$(AMSVER)/switch
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
|
||||
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/0100000000000034
|
||||
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 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/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/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/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/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.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 ../;
|
||||
rm -r atmosphere-$(AMSVER)-debug
|
||||
mv atmosphere-$(AMSVER)-debug.zip out/atmosphere-$(AMSVER)-debug.zip
|
||||
|
||||
@@ -27,7 +27,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the Atmosphère project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project as GPLv2 or later.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license.
|
||||
|
||||
Credits
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,34 +1,4 @@
|
||||
# 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
|
||||
+ 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.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018-2020 Atmosphère-NX
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emuMMC
|
||||
branch = develop
|
||||
commit = b168ddf5fbb31013ff529a4859110c82b11eb361
|
||||
parent = c07f54f3709a4710e0aead6c91139fa0893b5e5c
|
||||
commit = d12dd5464422029a1e5601916517ec3f1c81d8d0
|
||||
parent = 259a1a7513236a1de4d373bc6cb99032ede2c626
|
||||
method = rebase
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 10.0.0**
|
||||
**1.0.0 - 9.1.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#include "offsets/900_exfat.h"
|
||||
#include "offsets/910.h"
|
||||
#include "offsets/910_exfat.h"
|
||||
#include "offsets/1000.h"
|
||||
#include "offsets/1000_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#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(_910);
|
||||
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) {
|
||||
switch (version) {
|
||||
@@ -165,10 +161,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_910));
|
||||
case FS_VER_9_1_0_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:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
||||
@@ -65,9 +65,6 @@ enum FS_VER
|
||||
FS_VER_9_1_0,
|
||||
FS_VER_9_1_0_EXFAT,
|
||||
|
||||
FS_VER_10_0_0,
|
||||
FS_VER_10_0_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -36,6 +36,7 @@ sdmmc_storage_t sd_storage;
|
||||
|
||||
// init vars
|
||||
bool custom_driver = true;
|
||||
extern const volatile emuMMC_ctx_t emuMMC_ctx;
|
||||
|
||||
// FS funcs
|
||||
_sdmmc_accessor_gc sdmmc_accessor_gc;
|
||||
@@ -343,7 +344,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
// Close file handles and unmount
|
||||
|
||||
@@ -50,18 +50,8 @@ extern "C" {
|
||||
* @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 [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping.
|
||||
*/
|
||||
Result svcQueryIoMapping(u64* virtaddr, u64* out_size, 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);
|
||||
Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
|
||||
|
||||
/**
|
||||
* @brief Attaches a device address space to a device.
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
.endm
|
||||
|
||||
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]!
|
||||
SVC 0x55
|
||||
LDR X2, [SP], #16
|
||||
|
||||
@@ -25,12 +25,11 @@ enum FatalReason
|
||||
Fatal_InvalidAccessor,
|
||||
Fatal_ReadNoAccessor,
|
||||
Fatal_WriteNoAccessor,
|
||||
Fatal_IoMappingLegacy,
|
||||
Fatal_IoMapping,
|
||||
Fatal_UnknownVersion,
|
||||
Fatal_BadResult,
|
||||
Fatal_GetConfig,
|
||||
Fatal_CloseAccessor,
|
||||
Fatal_IoMapping,
|
||||
Fatal_Max
|
||||
};
|
||||
|
||||
|
||||
@@ -38,15 +38,8 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
|
||||
u64 vaddr;
|
||||
u64 aligned_addr = (io_addr & ~0xFFFul);
|
||||
u64 aligned_size = io_size + (io_addr - aligned_addr);
|
||||
if (emuMMC_ctx.fs_ver >= FS_VER_10_0_0) {
|
||||
u64 out_size;
|
||||
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);
|
||||
}
|
||||
if (svcQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
|
||||
fatal_abort(Fatal_IoMapping);
|
||||
}
|
||||
return (uintptr_t)(vaddr + (io_addr - aligned_addr));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "../emuMMC/emummc_ctx.h"
|
||||
|
||||
intptr_t QueryIoMapping(u64 addr, u64 size);
|
||||
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
@@ -38,6 +37,4 @@ void usleep(u64 ticks);
|
||||
void msleep(u64 milliseconds);
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
|
||||
extern volatile emuMMC_ctx_t emuMMC_ctx;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -263,20 +263,19 @@ uint32_t fuse_get_5x_key_generation(void) {
|
||||
/* Returns the fuse version expected for the firmware. */
|
||||
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
|
||||
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
|
||||
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_1000] = 13,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
|
||||
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
|
||||
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
|
||||
};
|
||||
|
||||
if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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_MEMORY_MAP_H
|
||||
#define EXOSPHERE_MEMORY_MAP_H
|
||||
|
||||
@@ -48,11 +48,9 @@
|
||||
#define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */
|
||||
#define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */
|
||||
#define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */
|
||||
#define _MMAPDEV18 ( 0x7001C000ull, 0x1000ull, true ) /* MC0 */
|
||||
#define _MMAPDEV19 ( 0x7001D000ull, 0x1000ull, true ) /* MC1 */
|
||||
#define _MMAPDEV20 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */
|
||||
#define _MMAPDEV21 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
|
||||
#define _MMAPDEV22 ( 0x40038000ull, 0x1000ull, true ) /* DEBUG: IRAM */
|
||||
#define _MMAPDEV18 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */
|
||||
#define _MMAPDEV19 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
|
||||
#define _MMAPDEV20 ( 0x40038000ull, 0x5000ull, true ) /* DEBUG: IRAM */
|
||||
|
||||
/* MMIO 7.0.0+. (addr). */
|
||||
#define _MMAPDEV7X0 ( 0x50041000ull ) /* ARM Interrupt Distributor */
|
||||
@@ -73,11 +71,9 @@
|
||||
#define _MMAPDEV7X15 ( 0x6000D000ull ) /* GPIO-1 - GPIO-8 */
|
||||
#define _MMAPDEV7X16 ( 0x7000C000ull ) /* I2C-I2C4 */
|
||||
#define _MMAPDEV7X17 ( 0x6000F000ull ) /* Exception vectors */
|
||||
#define _MMAPDEV7X18 ( 0x7001C000ull ) /* MC0 */
|
||||
#define _MMAPDEV7X19 ( 0x7001D000ull ) /* MC1 */
|
||||
#define _MMAPDEV7X20 ( 0x00000000ull ) /* AMS irampage, NOT mapped at startup */
|
||||
#define _MMAPDEV7X21 ( 0x00000000ull ) /* AMS userpage, NOT mapped at startup */
|
||||
#define _MMAPDEV7X22 ( 0x40038000ull ) /* DEBUG: IRAM */
|
||||
#define _MMAPDEV7X18 ( 0x00000000ull ) /* AMS irampage, NOT mapped at startup */
|
||||
#define _MMAPDEV7X19 ( 0x00000000ull ) /* AMS userpage, NOT mapped at startup */
|
||||
#define _MMAPDEV7X20 ( 0x40038000ull ) /* DEBUG: IRAM */
|
||||
|
||||
/* LP0 entry ram segments (addr, size, additional attributes) */
|
||||
#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_DTV_I2C234 16
|
||||
#define MMIO_DEVID_EXCEPTION_VECTORS 17
|
||||
#define MMIO_DEVID_MC0 18
|
||||
#define MMIO_DEVID_MC1 19
|
||||
#define MMIO_DEVID_AMS_IRAM_PAGE 20
|
||||
#define MMIO_DEVID_AMS_USER_PAGE 21
|
||||
#define MMIO_DEVID_DEBUG_IRAM 22
|
||||
#define MMIO_DEVID_MAX 23
|
||||
#define MMIO_DEVID_AMS_IRAM_PAGE 18
|
||||
#define MMIO_DEVID_AMS_USER_PAGE 19
|
||||
#define MMIO_DEVID_DEBUG_IRAM 20
|
||||
#define MMIO_DEVID_MAX 21
|
||||
|
||||
#define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0
|
||||
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1
|
||||
|
||||
@@ -149,7 +149,6 @@ static void setup_se(void) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
|
||||
break;
|
||||
}
|
||||
@@ -339,7 +338,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
|
||||
|
||||
/* Perform version checks. */
|
||||
/* We will be compatible with all package2s released before current, but not newer ones. */
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1000_CURRENT) {
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_910_CURRENT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -467,7 +466,6 @@ static void copy_warmboot_bin_to_dram() {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
warmboot_src = (uint8_t *)0x4003E000;
|
||||
break;
|
||||
}
|
||||
@@ -553,9 +551,6 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x18C;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x1AD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_810 0xB
|
||||
#define PACKAGE2_MAXVER_900 0xC
|
||||
#define PACKAGE2_MAXVER_910_920 0xD
|
||||
#define PACKAGE2_MAXVER_1000_CURRENT 0xE
|
||||
#define PACKAGE2_MAXVER_910_CURRENT 0xD
|
||||
|
||||
#define PACKAGE2_MINVER_100 0x3
|
||||
#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_810 0xC
|
||||
#define PACKAGE2_MINVER_900 0xD
|
||||
#define PACKAGE2_MINVER_910_920 0xE
|
||||
#define PACKAGE2_MINVER_1000_CURRENT 0xF
|
||||
#define PACKAGE2_MINVER_910_CURRENT 0xE
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
|
||||
@@ -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 = {};
|
||||
@@ -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
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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 <string.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.size = 0;
|
||||
}
|
||||
|
||||
|
||||
flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll));
|
||||
}
|
||||
|
||||
void set_security_engine_callback(unsigned int (*callback)(void)) {
|
||||
/* Set the callback. */
|
||||
g_se_callback = callback;
|
||||
if (callback == NULL || g_se_callback != NULL) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
/* Enable SE Interrupt firing for async op. */
|
||||
se_get_regs()->SE_INT_ENABLE = 0x10;
|
||||
g_se_callback = callback;
|
||||
}
|
||||
|
||||
/* Fires on Security Engine operation completion. */
|
||||
void se_operation_completed(void) {
|
||||
se_get_regs()->SE_INT_ENABLE = 0;
|
||||
unsigned int (*callback)(void) = g_se_callback;
|
||||
if (callback != NULL) {
|
||||
if (g_se_callback != NULL) {
|
||||
g_se_callback();
|
||||
g_se_callback = NULL;
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +103,7 @@ void se_validate_stored_vector(void) {
|
||||
|
||||
uint8_t calc_vector[0x10];
|
||||
se_generate_test_vector(calc_vector);
|
||||
|
||||
|
||||
/* Ensure nobody's messed with the security engine while we slept. */
|
||||
if (memcmp(calc_vector, g_se_stored_test_vector, 0x10) != 0) {
|
||||
generic_panic();
|
||||
@@ -123,7 +122,7 @@ void se_generate_stored_vector(void) {
|
||||
/* Set the flags for an AES keyslot. */
|
||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -142,7 +141,7 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||
/* Set the flags for an RSA keyslot. */
|
||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -161,7 +160,7 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||
|
||||
void clear_aes_keyslot(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -175,7 +174,7 @@ void clear_aes_keyslot(unsigned int keyslot) {
|
||||
|
||||
void clear_rsa_keyslot(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
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) {
|
||||
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) {
|
||||
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)) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
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_security_engine_callback(callback);
|
||||
|
||||
/* Enable SE Interrupt firing for async op. */
|
||||
se->SE_INT_ENABLE = 0x10;
|
||||
|
||||
/* Setup Input/Output lists */
|
||||
se->SE_IN_LL_ADDR = in_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);
|
||||
}
|
||||
|
||||
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();
|
||||
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. */
|
||||
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);
|
||||
@@ -356,6 +358,9 @@ void se_exp_mod(unsigned int keyslot, const void *buf, size_t size, unsigned int
|
||||
|
||||
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);
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
se_ll_t in_ll;
|
||||
|
||||
|
||||
ll_init(&in_ll, (void *)buf, size);
|
||||
|
||||
/* 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(&out_ll, dst, dst_size);
|
||||
|
||||
|
||||
__dsb_sy();
|
||||
|
||||
/* Set the LLs. */
|
||||
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
|
||||
se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll);
|
||||
|
||||
|
||||
/* Set registers for operation. */
|
||||
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||
se->SE_OPERATION = op;
|
||||
(void)(se->SE_OPERATION);
|
||||
|
||||
|
||||
__dsb_ish();
|
||||
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
|
||||
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) {
|
||||
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
if (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. */
|
||||
uint8_t derived_key[0x10] = {0};
|
||||
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_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
|
||||
clear_aes_keyslot_iv(keyslot);
|
||||
|
||||
|
||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||
/* Handle aligned blocks. */
|
||||
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);
|
||||
se->SE_CRYPTO_CONFIG |= 0x80;
|
||||
}
|
||||
|
||||
|
||||
/* Create final block. */
|
||||
uint8_t last_block[0x10] = {0};
|
||||
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) {
|
||||
memcpy(last_block, data + data_size - 0x10, 0x10);
|
||||
}
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < 0x10; i++) {
|
||||
last_block[i] ^= derived_key[i];
|
||||
}
|
||||
|
||||
|
||||
/* Perform last operation. */
|
||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
|
||||
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144;
|
||||
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. */
|
||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
/* Setup config for SHA256, size = BITS(src_size) */
|
||||
se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
||||
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[2] = 0;
|
||||
se->SE_SHA_MSG_LEFT[3] = 0;
|
||||
|
||||
|
||||
/* Trigger the operation. */
|
||||
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 */
|
||||
void se_initialize_rng(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -772,7 +777,7 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
||||
/* SE context save API. */
|
||||
void se_set_in_context_save_mode(bool is_context_save_mode) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
uint32_t val = se->SE_SE_SECURITY;
|
||||
if (is_context_save_mode) {
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) {
|
||||
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_RNG_CONFIG = 4;
|
||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||
|
||||
|
||||
/* Generate low part of key. */
|
||||
se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8);
|
||||
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) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
|
||||
se->SE_CONFIG = (ALG_RNG | DST_SRK);
|
||||
se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108;
|
||||
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). */
|
||||
se_generate_random_key(srkgen_keyslot, rng_keyslot);
|
||||
se_generate_srk(srkgen_keyslot);
|
||||
|
||||
|
||||
flush_dcache_range(work_buf, work_buf + 0x10);
|
||||
se_generate_random(rng_keyslot, work_buf, 0x10);
|
||||
flush_dcache_range(work_buf, work_buf + 0x10);
|
||||
|
||||
|
||||
/* Save random initial block. */
|
||||
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM);
|
||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst, 0x10, work_buf, 0x10);
|
||||
|
||||
|
||||
/* Save Sticky Bits. */
|
||||
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_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Save AES Key Table. */
|
||||
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);
|
||||
@@ -869,21 +874,21 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
|
||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Save AES Original IVs. */
|
||||
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_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Save AES Updated IVs */
|
||||
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_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Save RSA Keytable. */
|
||||
uint8_t *rsa_ctx_out = (uint8_t *)dst + 0x430;
|
||||
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. " */
|
||||
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_CRYPTO_LAST_BLOCK = 0;
|
||||
se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10);
|
||||
|
||||
|
||||
/* Save SRK into PMC registers. */
|
||||
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK);
|
||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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_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);
|
||||
|
||||
/* 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_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);
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "synchronization.h"
|
||||
#include "masterkey.h"
|
||||
#include "mc.h"
|
||||
#include "mc0.h"
|
||||
#include "mc1.h"
|
||||
#include "memory_map.h"
|
||||
#include "pmc.h"
|
||||
#include "randomcache.h"
|
||||
@@ -190,7 +188,6 @@ void set_version_specific_smcs(void) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
/* No more LoadSecureExpModKey. */
|
||||
g_smc_user_table[0xE].handler = NULL;
|
||||
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 res = get_exp_mod_result();
|
||||
if (res == 0) {
|
||||
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;
|
||||
}
|
||||
if (get_exp_mod_done() != 1) {
|
||||
return 3;
|
||||
}
|
||||
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) {
|
||||
@@ -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 titlekey[0x10];
|
||||
uint64_t sealed_titlekey[2];
|
||||
uint32_t res = get_exp_mod_result();
|
||||
if (res == 0) {
|
||||
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;
|
||||
}
|
||||
if (get_exp_mod_done() != 1) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -619,7 +616,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||
}
|
||||
/* Check for PMC registers. */
|
||||
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,
|
||||
0x00, 0x00, 0x00, 0x17, 0x00, 0xC4, 0x07, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00,
|
||||
@@ -635,83 +632,39 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
static const uint8_t mc_whitelist_5x[0xD00/(sizeof(uint32_t) * 8)] = {
|
||||
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
|
||||
0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04,
|
||||
0x80, 0xFF, 0x08, 0x80, 0x03, 0x38, 0x8E, 0x1F,
|
||||
0xC8, 0xFF, 0xFF, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0xF0, 0x1F, 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, 0xE4, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 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,
|
||||
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00,
|
||||
};
|
||||
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);
|
||||
}
|
||||
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
|
||||
address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + MMIO_GET_DEVICE_SIZE(MMIO_DEVID_MC)) {
|
||||
/* Memory Controller RW supported only on 4.0.0+ */
|
||||
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 - 0x70019000);
|
||||
uint32_t wl_ind = (offset >> 5);
|
||||
/* If address is whitelisted, allow write. */
|
||||
if (wl_ind < sizeof(mc_whitelist) && (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) {
|
||||
p_mmio = (volatile uint32_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC) + offset);
|
||||
} else {
|
||||
/* 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. */
|
||||
if (address == 0x7001923C || address == 0x70019298) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,16 +683,9 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||
/* Return old value. */
|
||||
args->X[1] = old_value;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,93 +34,12 @@
|
||||
|
||||
/* Globals. */
|
||||
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 __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_imported_exponents[4][0x100];
|
||||
|
||||
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) {
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
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_900:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
default:
|
||||
return keyslot <= 5;
|
||||
}
|
||||
}
|
||||
|
||||
void set_exp_mod_result(uint32_t result) {
|
||||
g_exp_mod_result = result;
|
||||
void set_exp_mod_done(bool done) {
|
||||
g_exp_mod_done = done;
|
||||
}
|
||||
|
||||
uint32_t get_exp_mod_result(void) {
|
||||
return g_exp_mod_result;
|
||||
bool get_exp_mod_done(void) {
|
||||
return g_exp_mod_done;
|
||||
}
|
||||
|
||||
uint32_t exp_mod_done_handler(void) {
|
||||
set_exp_mod_result(0);
|
||||
set_exp_mod_done(true);
|
||||
|
||||
se_trigger_interrupt();
|
||||
|
||||
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) {
|
||||
uint8_t modulus[0x100];
|
||||
uint8_t exponent[0x100];
|
||||
@@ -207,8 +108,7 @@ uint32_t user_exp_mod(smc_args_t *args) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
set_exp_mod_result(3);
|
||||
|
||||
set_exp_mod_done(false);
|
||||
/* Hardcode RSA keyslot 0. */
|
||||
set_rsa_keyslot(0, modulus, 0x100, exponent, exponent_size);
|
||||
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;
|
||||
}
|
||||
|
||||
set_exp_mod_result(3);
|
||||
|
||||
set_exp_mod_done(false);
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[exponent_id], 0x100);
|
||||
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -811,7 +700,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
set_exp_mod_result(3);
|
||||
set_exp_mod_done(false);
|
||||
|
||||
/* Expected label_hash occupies args->X[3] to args->X[6]. */
|
||||
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;
|
||||
bool import_modulus;
|
||||
|
||||
switch (usecase) {
|
||||
case 0:
|
||||
@@ -1000,33 +888,22 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
|
||||
return 0;
|
||||
case 1:
|
||||
exponent_id = 1;
|
||||
import_modulus = false;
|
||||
break;
|
||||
case 2:
|
||||
exponent_id = 0;
|
||||
import_modulus = true;
|
||||
break;
|
||||
case 3:
|
||||
exponent_id = 2;
|
||||
import_modulus = false;
|
||||
break;
|
||||
case 4:
|
||||
exponent_id = 3;
|
||||
import_modulus = true;
|
||||
break;
|
||||
default:
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
/* Modulus import isn't implemented on < 10.0.0. */
|
||||
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_1000);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* Copy key to global. */
|
||||
memcpy(g_imported_exponents[exponent_id], user_data, 0x100);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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_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);
|
||||
bool get_crypt_aes_done(void);
|
||||
|
||||
void set_exp_mod_result(uint32_t result);
|
||||
uint32_t get_exp_mod_result(void);
|
||||
void set_exp_mod_done(bool done);
|
||||
bool get_exp_mod_done(void);
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -25,10 +25,14 @@
|
||||
#include "masterkey.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. */
|
||||
void tkey_set_expected_label_hash(uint64_t *label_hash) {
|
||||
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) {
|
||||
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) {
|
||||
@@ -47,7 +51,7 @@ static void tkey_validate_type(unsigned int type) {
|
||||
|
||||
void tkey_set_type(unsigned int 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 */
|
||||
@@ -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;
|
||||
|
||||
/* 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. */
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/* Generate the appropriate titlekek into keyslot 9. */
|
||||
unsigned int master_keyslot = mkey_get_keyslot(g_rsa_shared_data.unwrap_titlekey.master_key_rev);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_sources[g_rsa_shared_data.unwrap_titlekey.type], 0x10);
|
||||
unsigned int master_keyslot = mkey_get_keyslot(g_tkey_master_key_rev);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_sources[g_tkey_type], 0x10);
|
||||
|
||||
/* Unwrap the titlekey using the titlekek. */
|
||||
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, dst, 0x10, src, 0x10);
|
||||
|
||||
@@ -13,12 +13,11 @@
|
||||
* 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_TITLEKEY_H
|
||||
#define EXOSPHERE_TITLEKEY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rsa_common.h"
|
||||
|
||||
#define TITLEKEY_TYPE_MAX 0x1
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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 "utils.h"
|
||||
#include "memory_map.h"
|
||||
#include "mc.h"
|
||||
@@ -65,7 +65,7 @@ void init_dma_controllers(unsigned int target_firmware) {
|
||||
MAKE_REG32(0x6000C038) = 0x0;
|
||||
|
||||
/* 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 */
|
||||
MAKE_REG32(0x6000C004) = 0x40060;
|
||||
@@ -99,7 +99,7 @@ void init_dma_controllers(unsigned int target_firmware) {
|
||||
MAKE_REG32(0x60020038) = 0;
|
||||
|
||||
/* 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 */
|
||||
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) {
|
||||
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.
|
||||
@@ -205,12 +197,12 @@ void warmboot_init(void) {
|
||||
*/
|
||||
flush_dcache_all();
|
||||
invalidate_icache_all();
|
||||
|
||||
|
||||
/* On warmboot (not cpu_on) only */
|
||||
if (VIRT_MC_SECURITY_CFG3 == 0) {
|
||||
init_dma_controllers(g_exosphere_target_firmware_for_init);
|
||||
}
|
||||
|
||||
|
||||
/*identity_remap_tzram();*/
|
||||
/* 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) {
|
||||
|
||||
@@ -82,9 +82,6 @@ typedef enum {
|
||||
FS_VER_9_1_0,
|
||||
FS_VER_9_1_0_EXFAT,
|
||||
|
||||
FS_VER_10_0_0,
|
||||
FS_VER_10_0_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
} emummc_fs_ver_t;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
"\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) {
|
||||
|
||||
@@ -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 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 */
|
||||
/* 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(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(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(1000, 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(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(900, 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(700, 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(900, 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(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(700, 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(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
|
||||
|
||||
/* Hook Definitions. */
|
||||
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,
|
||||
|
||||
/* Kernel Infos. */
|
||||
@@ -897,15 +811,6 @@ static const kernel_info_t g_kernel_infos[] = {
|
||||
.embedded_ini_ptr = 0x180,
|
||||
.free_code_space_offset = 0x65780,
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
*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));
|
||||
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. */
|
||||
*kernel_size = kernel_ldr_offset + kernel_ldr_bin_size;
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@
|
||||
|
||||
#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
|
||||
@@ -160,7 +160,6 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
||||
desired_keyblob = MASTERKEY_REVISION_900;
|
||||
/* Fallthrough */
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_1000:
|
||||
desired_keyblob = MASTERKEY_REVISION_910_CURRENT;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -232,8 +232,6 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_900;
|
||||
} else if (memcmp(package1loader_header->build_timestamp, "20191021", 8) == 0) {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_910;
|
||||
} else if (memcmp(package1loader_header->build_timestamp, "20200303", 8) == 0) {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_1000;
|
||||
} else {
|
||||
fatal_error("[NXBOOT] Unable to identify package1!\n");
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
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. */
|
||||
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. */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
#define PACKAGE2_MAXVER_700_800 0xA
|
||||
#define PACKAGE2_MAXVER_810 0xB
|
||||
#define PACKAGE2_MAXVER_900 0xC
|
||||
#define PACKAGE2_MAXVER_910_920 0xD
|
||||
#define PACKAGE2_MAXVER_1000_CURRENT 0xE
|
||||
#define PACKAGE2_MAXVER_910_CURRENT 0xD
|
||||
|
||||
#define PACKAGE2_MINVER_100 0x3
|
||||
#define PACKAGE2_MINVER_200 0x4
|
||||
@@ -53,8 +52,7 @@
|
||||
#define PACKAGE2_MINVER_700_800 0xB
|
||||
#define PACKAGE2_MINVER_810 0xC
|
||||
#define PACKAGE2_MINVER_900 0xD
|
||||
#define PACKAGE2_MINVER_910_920 0xE
|
||||
#define PACKAGE2_MINVER_1000_CURRENT 0xF
|
||||
#define PACKAGE2_MINVER_910_CURRENT 0xE
|
||||
|
||||
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = c1fe12fcbd661ae47673af5f224804c92eebdbb5
|
||||
parent = 98cc051387515977dcdede8ab0f1b09077f2f24b
|
||||
commit = a40d4593d7e46ea296802e5c50fd0da2d9f92a76
|
||||
parent = 6de1361c8be886eda16faf87c73b9e4d01187bca
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -10,7 +10,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the atmosphere-libs project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the atmosphere-libs project as GPLv2 or later.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the atmosphere-libs project under the Zero-Clause BSD license.
|
||||
|
||||
Credits
|
||||
|
||||
@@ -5,7 +5,7 @@ endif
|
||||
include $(DEVKITPRO)/devkitA64/base_rules
|
||||
|
||||
export ATMOSPHERE_DEFINES += -DATMOSPHERE_ARCH_ARM64
|
||||
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mtp=soft
|
||||
export ATMOSPHERE_SETTINGS += -march=armv8-a -mtp=soft
|
||||
export ATMOSPHERE_CFLAGS +=
|
||||
export ATMOSPHERE_CXXFLAGS +=
|
||||
export ATMOSPHERE_ASFLAGS +=
|
||||
|
||||
@@ -6,8 +6,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
#PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/mesosphere.hpp
|
||||
PRECOMPILED_HEADERS :=
|
||||
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/mesosphere.hpp
|
||||
|
||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Werror -fno-non-call-exceptions
|
||||
|
||||
@@ -10,7 +10,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the libmesosphere project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the libmesosphere project as GPLv2 or later.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the libmesosphere project under the Zero-Clause BSD license.
|
||||
|
||||
Credits
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <mesosphere/kern_k_typed_address.hpp>
|
||||
#include <mesosphere/kern_select_cpu.hpp>
|
||||
#include <mesosphere/arch/arm64/kern_k_page_table_entry.hpp>
|
||||
#include <mesosphere/kern_select_system_control.hpp>
|
||||
|
||||
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. */
|
||||
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:
|
||||
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. */
|
||||
@@ -578,62 +363,32 @@ namespace ams::kern::arch::arm64::init {
|
||||
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 {
|
||||
public:
|
||||
struct State {
|
||||
uintptr_t next_address;
|
||||
uintptr_t free_bitmap;
|
||||
};
|
||||
private:
|
||||
State state;
|
||||
uintptr_t next_address;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KInitialPageAllocator() : state{} { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KInitialPageAllocator() : next_address(Null<uintptr_t>) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE void Initialize(uintptr_t address) {
|
||||
this->state.next_address = address + BITSIZEOF(this->state.free_bitmap) * PageSize;
|
||||
this->state.free_bitmap = ~uintptr_t();
|
||||
this->next_address = address;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) {
|
||||
if (kern::GetTargetFirmware() >= kern::TargetFirmware_10_0_0) {
|
||||
this->state = *reinterpret_cast<State *>(state_val);
|
||||
} else {
|
||||
this->state.next_address = state_val;
|
||||
this->state.free_bitmap = 0;
|
||||
}
|
||||
ALWAYS_INLINE uintptr_t GetFinalNextAddress() {
|
||||
const uintptr_t final_address = this->next_address;
|
||||
this->next_address = Null<uintptr_t>;
|
||||
return final_address;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void GetFinalState(State *out) {
|
||||
*out = this->state;
|
||||
this->state = {};
|
||||
ALWAYS_INLINE uintptr_t GetFinalState() {
|
||||
return this->GetFinalNextAddress();
|
||||
}
|
||||
public:
|
||||
virtual KPhysicalAddress Allocate() override {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(this->state.next_address != Null<uintptr_t>);
|
||||
uintptr_t allocated = this->state.next_address;
|
||||
if (this->state.free_bitmap != 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(this->next_address != Null<uintptr_t>);
|
||||
const uintptr_t allocated = this->next_address;
|
||||
this->next_address += PageSize;
|
||||
std::memset(reinterpret_cast<void *>(allocated), 0, PageSize);
|
||||
return allocated;
|
||||
}
|
||||
|
||||
@@ -31,12 +31,6 @@ namespace ams::kern::arch::arm64 {
|
||||
public:
|
||||
struct InvalidTag{};
|
||||
|
||||
enum ExtensionTag : u64 {
|
||||
ExtensionTag_IsValidBit = (1ul << 56),
|
||||
ExtensionTag_IsValid = (ExtensionTag_IsValidBit | (1ul << 0)),
|
||||
ExtensionTag_IsBlockMask = (ExtensionTag_IsValidBit | (1ul << 1)),
|
||||
};
|
||||
|
||||
enum Permission : u64 {
|
||||
Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)),
|
||||
Permission_KernelRX = ((0ul << 53) | (1ul << 54) | (2ul << 6)),
|
||||
@@ -95,7 +89,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Construct a new attribute. */
|
||||
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 IsUserAccessible() const { return this->GetBits(6, 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 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) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; }
|
||||
@@ -164,10 +157,6 @@ namespace ams::kern::arch::arm64 {
|
||||
return this->attributes == attr;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const {
|
||||
return this->attributes;
|
||||
}
|
||||
|
||||
protected:
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributes() const {
|
||||
return this->attributes;
|
||||
@@ -197,7 +186,7 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
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)
|
||||
: 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(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 {
|
||||
return this->SelectBits(12, 36);
|
||||
|
||||
@@ -20,24 +20,6 @@ namespace ams::kern {
|
||||
|
||||
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)
|
||||
|
||||
@@ -94,7 +94,6 @@ namespace ams::kern {
|
||||
KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const;
|
||||
|
||||
void Update(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr);
|
||||
void UpdateLock(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, void (KMemoryBlock::*lock_func)(KMemoryPermission new_perm), KMemoryPermission perm);
|
||||
|
||||
iterator FindIterator(KProcessAddress address) const {
|
||||
return this->memory_block_tree.find(KMemoryBlock(address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None));
|
||||
|
||||
@@ -197,7 +197,6 @@ namespace ams::kern {
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
/* Find the iterator now that we've updated. */
|
||||
@@ -228,86 +227,6 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
|
||||
void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, void (KMemoryBlock::*lock_func)(KMemoryPermission new_perm), KMemoryPermission perm) {
|
||||
/* Ensure for auditing that we never end up with an invalid tree. */
|
||||
KScopedMemoryBlockManagerAuditor auditor(this);
|
||||
MESOSPHERE_ASSERT(util::IsAligned(GetInteger(address), PageSize));
|
||||
|
||||
KProcessAddress cur_address = address;
|
||||
size_t remaining_pages = num_pages;
|
||||
iterator it = this->FindIterator(address);
|
||||
iterator prev = it, next = it;
|
||||
bool check_coalesce_prev = false, check_coalesce_next = false;
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
|
||||
/* If we need to, create a new block before and insert it. */
|
||||
if (cur_info.address != GetInteger(cur_address)) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address);
|
||||
it = this->memory_block_tree.insert(*new_block);
|
||||
it++;
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
cur_address = cur_info.GetAddress();
|
||||
} else if (cur_address == address && cur_address != this->start_address) {
|
||||
/* If there's a previous, we should check for coalescing. */
|
||||
check_coalesce_prev = true;
|
||||
prev--;
|
||||
} else if (cur_info.GetSize() > remaining_size) {
|
||||
/* If we need to, create a new block after and insert it. */
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address + remaining_size);
|
||||
it = this->memory_block_tree.insert(*new_block);
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
} else if (cur_info.GetSize() == remaining_size) {
|
||||
/* Otherwise if we can map precisely, we may need to check for coalescing against next block. */
|
||||
next = it;
|
||||
++next;
|
||||
if (next != this->memory_block_tree.end()) {
|
||||
check_coalesce_next = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call the locked update function. */
|
||||
(std::addressof(*it)->*lock_func)(perm);
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
it++;
|
||||
}
|
||||
|
||||
/* If we should try to coalesce prev, do so. */
|
||||
if (check_coalesce_prev) {
|
||||
it = prev;
|
||||
it++;
|
||||
if (prev->HasSameProperties(*it)) {
|
||||
KMemoryBlock *block = std::addressof(*it);
|
||||
const size_t pages = it->GetNumPages();
|
||||
this->memory_block_tree.erase(it);
|
||||
allocator->Free(block);
|
||||
prev->Add(pages);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we should try to coalesce next, do so. */
|
||||
if (check_coalesce_next) {
|
||||
it = next;
|
||||
it--;
|
||||
if (it->HasSameProperties(*next)) {
|
||||
KMemoryBlock *block = std::addressof(*next);
|
||||
const size_t pages = next->GetNumPages();
|
||||
this->memory_block_tree.erase(next);
|
||||
allocator->Free(block);
|
||||
it->Add(pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug. */
|
||||
bool KMemoryBlockManager::CheckState() const {
|
||||
/* If we fail, we should dump blocks. */
|
||||
|
||||
@@ -14,7 +14,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the libstratosphere project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the libstratosphere project as GPLv2 or later.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the libstratosphere project under the Zero-Clause BSD license.
|
||||
|
||||
Credits
|
||||
|
||||
@@ -20,50 +20,46 @@
|
||||
#include <vapours.hpp>
|
||||
|
||||
/* Libstratosphere-only utility. */
|
||||
#include <stratosphere/util.hpp>
|
||||
#include "stratosphere/util.hpp"
|
||||
|
||||
/* Sadly required shims. */
|
||||
#include <stratosphere/svc/svc_stratosphere_shims.hpp>
|
||||
#include "stratosphere/svc/svc_stratosphere_shims.hpp"
|
||||
|
||||
/* Critical modules with no dependencies. */
|
||||
#include <stratosphere/ams.hpp>
|
||||
#include <stratosphere/os.hpp>
|
||||
#include <stratosphere/dd.hpp>
|
||||
#include <stratosphere/lmem.hpp>
|
||||
#include <stratosphere/mem.hpp>
|
||||
#include "stratosphere/ams.hpp"
|
||||
#include "stratosphere/os.hpp"
|
||||
#include "stratosphere/dd.hpp"
|
||||
#include "stratosphere/lmem.hpp"
|
||||
#include "stratosphere/mem.hpp"
|
||||
|
||||
/* Pull in all ID definitions from NCM. */
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include "stratosphere/ncm/ncm_ids.hpp"
|
||||
|
||||
/* At this point, just include the rest alphabetically. */
|
||||
/* TODO: Figure out optimal order. */
|
||||
#include <stratosphere/boot2.hpp>
|
||||
#include <stratosphere/cfg.hpp>
|
||||
#include <stratosphere/dmnt.hpp>
|
||||
#include <stratosphere/erpt.hpp>
|
||||
#include <stratosphere/fatal.hpp>
|
||||
#include <stratosphere/hid.hpp>
|
||||
#include <stratosphere/hos.hpp>
|
||||
#include <stratosphere/kvdb.hpp>
|
||||
#include <stratosphere/ldr.hpp>
|
||||
#include <stratosphere/lr.hpp>
|
||||
#include <stratosphere/map.hpp>
|
||||
#include <stratosphere/ncm.hpp>
|
||||
#include <stratosphere/nim.hpp>
|
||||
#include <stratosphere/patcher.hpp>
|
||||
#include <stratosphere/pgl.hpp>
|
||||
#include <stratosphere/psc.hpp>
|
||||
#include <stratosphere/pm.hpp>
|
||||
#include <stratosphere/reg.hpp>
|
||||
#include <stratosphere/ro.hpp>
|
||||
#include <stratosphere/settings.hpp>
|
||||
#include <stratosphere/sf.hpp>
|
||||
#include <stratosphere/sm.hpp>
|
||||
#include <stratosphere/spl.hpp>
|
||||
#include <stratosphere/time.hpp>
|
||||
#include <stratosphere/updater.hpp>
|
||||
#include "stratosphere/boot2.hpp"
|
||||
#include "stratosphere/cfg.hpp"
|
||||
#include "stratosphere/dmnt.hpp"
|
||||
#include "stratosphere/fatal.hpp"
|
||||
#include "stratosphere/hid.hpp"
|
||||
#include "stratosphere/hos.hpp"
|
||||
#include "stratosphere/kvdb.hpp"
|
||||
#include "stratosphere/ldr.hpp"
|
||||
#include "stratosphere/lr.hpp"
|
||||
#include "stratosphere/map.hpp"
|
||||
#include "stratosphere/ncm.hpp"
|
||||
#include "stratosphere/nim.hpp"
|
||||
#include "stratosphere/patcher.hpp"
|
||||
#include "stratosphere/pm.hpp"
|
||||
#include "stratosphere/reg.hpp"
|
||||
#include "stratosphere/ro.hpp"
|
||||
#include "stratosphere/settings.hpp"
|
||||
#include "stratosphere/sf.hpp"
|
||||
#include "stratosphere/sm.hpp"
|
||||
#include "stratosphere/spl.hpp"
|
||||
#include "stratosphere/updater.hpp"
|
||||
|
||||
/* Include FS last. */
|
||||
#include <stratosphere/fs.hpp>
|
||||
#include <stratosphere/fssrv.hpp>
|
||||
#include <stratosphere/fssystem.hpp>
|
||||
#include "stratosphere/fs.hpp"
|
||||
#include "stratosphere/fssrv.hpp"
|
||||
#include "stratosphere/fssystem.hpp"
|
||||
@@ -35,7 +35,6 @@ namespace ams::exosphere {
|
||||
AMS_DEFINE_TARGET_FIRMWARE_ENUM(810),
|
||||
AMS_DEFINE_TARGET_FIRMWARE_ENUM(900),
|
||||
AMS_DEFINE_TARGET_FIRMWARE_ENUM(910),
|
||||
AMS_DEFINE_TARGET_FIRMWARE_ENUM(1000),
|
||||
};
|
||||
#undef AMS_DEFINE_TARGET_FIRMWARE_ENUM
|
||||
|
||||
|
||||
@@ -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 <stratosphere/erpt/erpt_ids.autogen.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
||||
#include <stratosphere/erpt/sf/erpt_sf_i_context.hpp>
|
||||
#include <stratosphere/erpt/sf/erpt_sf_i_session.hpp>
|
||||
#include <stratosphere/erpt/srv/erpt_srv_types.hpp>
|
||||
#include <stratosphere/erpt/srv/erpt_srv_api.hpp>
|
||||
@@ -1,780 +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>
|
||||
|
||||
/* NOTE: This file is auto-generated. */
|
||||
/* Do not make edits to this file by hand. */
|
||||
|
||||
#define AMS_ERPT_FOREACH_FIELD_TYPE(HANDLER) \
|
||||
HANDLER(FieldType_NumericU64, 0 ) \
|
||||
HANDLER(FieldType_NumericU32, 1 ) \
|
||||
HANDLER(FieldType_NumericI64, 2 ) \
|
||||
HANDLER(FieldType_NumericI32, 3 ) \
|
||||
HANDLER(FieldType_String, 4 ) \
|
||||
HANDLER(FieldType_U8Array, 5 ) \
|
||||
HANDLER(FieldType_U32Array, 6 ) \
|
||||
HANDLER(FieldType_U64Array, 7 ) \
|
||||
HANDLER(FieldType_I32Array, 8 ) \
|
||||
HANDLER(FieldType_I64Array, 9 ) \
|
||||
HANDLER(FieldType_Bool, 10) \
|
||||
HANDLER(FieldType_NumericU16, 11) \
|
||||
HANDLER(FieldType_NumericU8, 12) \
|
||||
HANDLER(FieldType_NumericI16, 13) \
|
||||
HANDLER(FieldType_NumericI8, 14) \
|
||||
HANDLER(FieldType_I8Array, 15) \
|
||||
|
||||
#define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \
|
||||
HANDLER(Test, 0 ) \
|
||||
HANDLER(ErrorInfo, 1 ) \
|
||||
HANDLER(ConnectionStatusInfo, 2 ) \
|
||||
HANDLER(NetworkInfo, 3 ) \
|
||||
HANDLER(NXMacAddressInfo, 4 ) \
|
||||
HANDLER(StealthNetworkInfo, 5 ) \
|
||||
HANDLER(LimitHighCapacityInfo, 6 ) \
|
||||
HANDLER(NATTypeInfo, 7 ) \
|
||||
HANDLER(WirelessAPMacAddressInfo, 8 ) \
|
||||
HANDLER(GlobalIPAddressInfo, 9 ) \
|
||||
HANDLER(EnableWirelessInterfaceInfo, 10 ) \
|
||||
HANDLER(EnableWifiInfo, 11 ) \
|
||||
HANDLER(EnableBluetoothInfo, 12 ) \
|
||||
HANDLER(EnableNFCInfo, 13 ) \
|
||||
HANDLER(NintendoZoneSSIDListVersionInfo, 14 ) \
|
||||
HANDLER(LANAdapterMacAddressInfo, 15 ) \
|
||||
HANDLER(ApplicationInfo, 16 ) \
|
||||
HANDLER(OccurrenceInfo, 17 ) \
|
||||
HANDLER(ProductModelInfo, 18 ) \
|
||||
HANDLER(CurrentLanguageInfo, 19 ) \
|
||||
HANDLER(UseNetworkTimeProtocolInfo, 20 ) \
|
||||
HANDLER(TimeZoneInfo, 21 ) \
|
||||
HANDLER(ControllerFirmwareInfo, 22 ) \
|
||||
HANDLER(VideoOutputInfo, 23 ) \
|
||||
HANDLER(NANDFreeSpaceInfo, 24 ) \
|
||||
HANDLER(SDCardFreeSpaceInfo, 25 ) \
|
||||
HANDLER(ScreenBrightnessInfo, 26 ) \
|
||||
HANDLER(AudioFormatInfo, 27 ) \
|
||||
HANDLER(MuteOnHeadsetUnpluggedInfo, 28 ) \
|
||||
HANDLER(NumUserRegisteredInfo, 29 ) \
|
||||
HANDLER(DataDeletionInfo, 30 ) \
|
||||
HANDLER(ControllerVibrationInfo, 31 ) \
|
||||
HANDLER(LockScreenInfo, 32 ) \
|
||||
HANDLER(InternalBatteryLotNumberInfo, 33 ) \
|
||||
HANDLER(LeftControllerSerialNumberInfo, 34 ) \
|
||||
HANDLER(RightControllerSerialNumberInfo, 35 ) \
|
||||
HANDLER(NotificationInfo, 36 ) \
|
||||
HANDLER(TVInfo, 37 ) \
|
||||
HANDLER(SleepInfo, 38 ) \
|
||||
HANDLER(ConnectionInfo, 39 ) \
|
||||
HANDLER(NetworkErrorInfo, 40 ) \
|
||||
HANDLER(FileAccessPathInfo, 41 ) \
|
||||
HANDLER(GameCardCIDInfo, 42 ) \
|
||||
HANDLER(NANDCIDInfo, 43 ) \
|
||||
HANDLER(MicroSDCIDInfo, 44 ) \
|
||||
HANDLER(NANDSpeedModeInfo, 45 ) \
|
||||
HANDLER(MicroSDSpeedModeInfo, 46 ) \
|
||||
HANDLER(GameCardSpeedModeInfo, 47 ) \
|
||||
HANDLER(UserAccountInternalIDInfo, 48 ) \
|
||||
HANDLER(NetworkServiceAccountInternalIDInfo, 49 ) \
|
||||
HANDLER(NintendoAccountInternalIDInfo, 50 ) \
|
||||
HANDLER(USB3AvailableInfo, 51 ) \
|
||||
HANDLER(CallStackInfo, 52 ) \
|
||||
HANDLER(SystemStartupLogInfo, 53 ) \
|
||||
HANDLER(RegionSettingInfo, 54 ) \
|
||||
HANDLER(NintendoZoneConnectedInfo, 55 ) \
|
||||
HANDLER(ForceSleepInfo, 56 ) \
|
||||
HANDLER(ChargerInfo, 57 ) \
|
||||
HANDLER(RadioStrengthInfo, 58 ) \
|
||||
HANDLER(ErrorInfoAuto, 59 ) \
|
||||
HANDLER(AccessPointInfo, 60 ) \
|
||||
HANDLER(ErrorInfoDefaults, 61 ) \
|
||||
HANDLER(SystemPowerStateInfo, 62 ) \
|
||||
HANDLER(PerformanceInfo, 63 ) \
|
||||
HANDLER(ThrottlingInfo, 64 ) \
|
||||
HANDLER(GameCardErrorInfo, 65 ) \
|
||||
HANDLER(EdidInfo, 66 ) \
|
||||
HANDLER(ThermalInfo, 67 ) \
|
||||
HANDLER(CradleFirmwareInfo, 68 ) \
|
||||
HANDLER(RunningApplicationInfo, 69 ) \
|
||||
HANDLER(RunningAppletInfo, 70 ) \
|
||||
HANDLER(FocusedAppletHistoryInfo, 71 ) \
|
||||
HANDLER(CompositorInfo, 72 ) \
|
||||
HANDLER(BatteryChargeInfo, 73 ) \
|
||||
HANDLER(NANDExtendedCsd, 74 ) \
|
||||
HANDLER(NANDPatrolInfo, 75 ) \
|
||||
HANDLER(NANDErrorInfo, 76 ) \
|
||||
HANDLER(NANDDriverLog, 77 ) \
|
||||
HANDLER(SdCardSizeSpec, 78 ) \
|
||||
HANDLER(SdCardErrorInfo, 79 ) \
|
||||
HANDLER(SdCardDriverLog , 80 ) \
|
||||
HANDLER(FsProxyErrorInfo, 81 ) \
|
||||
HANDLER(SystemAppletSceneInfo, 82 ) \
|
||||
HANDLER(VideoInfo, 83 ) \
|
||||
HANDLER(GpuErrorInfo, 84 ) \
|
||||
HANDLER(PowerClockInfo, 85 ) \
|
||||
HANDLER(AdspErrorInfo, 86 ) \
|
||||
HANDLER(NvDispDeviceInfo, 87 ) \
|
||||
HANDLER(NvDispDcWindowInfo, 88 ) \
|
||||
HANDLER(NvDispDpModeInfo, 89 ) \
|
||||
HANDLER(NvDispDpLinkSpec, 90 ) \
|
||||
HANDLER(NvDispDpLinkStatus, 91 ) \
|
||||
HANDLER(NvDispDpHdcpInfo, 92 ) \
|
||||
HANDLER(NvDispDpAuxCecInfo, 93 ) \
|
||||
HANDLER(NvDispDcInfo, 94 ) \
|
||||
HANDLER(NvDispDsiInfo, 95 ) \
|
||||
HANDLER(NvDispErrIDInfo, 96 ) \
|
||||
HANDLER(SdCardMountInfo, 97 ) \
|
||||
HANDLER(RetailInteractiveDisplayInfo, 98 ) \
|
||||
HANDLER(CompositorStateInfo, 99 ) \
|
||||
HANDLER(CompositorLayerInfo, 100) \
|
||||
HANDLER(CompositorDisplayInfo, 101) \
|
||||
HANDLER(CompositorHWCInfo, 102) \
|
||||
HANDLER(MonitorCapability, 103) \
|
||||
HANDLER(ErrorReportSharePermissionInfo, 104) \
|
||||
HANDLER(MultimediaInfo, 105) \
|
||||
HANDLER(ConnectedControllerInfo, 106) \
|
||||
HANDLER(FsMemoryInfo, 107) \
|
||||
HANDLER(UserClockContextInfo, 108) \
|
||||
HANDLER(NetworkClockContextInfo, 109) \
|
||||
HANDLER(AcpGeneralSettingsInfo, 110) \
|
||||
HANDLER(AcpPlayLogSettingsInfo, 111) \
|
||||
HANDLER(AcpAocSettingsInfo, 112) \
|
||||
HANDLER(AcpBcatSettingsInfo, 113) \
|
||||
HANDLER(AcpStorageSettingsInfo, 114) \
|
||||
HANDLER(AcpRatingSettingsInfo, 115) \
|
||||
HANDLER(MonitorSettings, 116) \
|
||||
HANDLER(RebootlessSystemUpdateVersionInfo, 117) \
|
||||
HANDLER(NifmConnectionTestInfo, 118) \
|
||||
HANDLER(PcieLoggedStateInfo, 119) \
|
||||
HANDLER(NetworkSecurityCertificateInfo, 120) \
|
||||
HANDLER(AcpNeighborDetectionInfo, 121) \
|
||||
HANDLER(GpuCrashInfo, 122) \
|
||||
HANDLER(UsbStateInfo, 123) \
|
||||
HANDLER(NvHostErrInfo, 124) \
|
||||
HANDLER(RunningUlaInfo, 125) \
|
||||
|
||||
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
|
||||
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \
|
||||
HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \
|
||||
HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \
|
||||
HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \
|
||||
HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \
|
||||
HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \
|
||||
HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \
|
||||
HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \
|
||||
HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \
|
||||
HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \
|
||||
HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \
|
||||
HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \
|
||||
HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AcpStartupUserAccount, 488, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \
|
||||
HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \
|
||||
HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \
|
||||
HANDLER(AcpUserAccountSwitchLock, 573, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \
|
||||
HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \
|
||||
HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \
|
||||
HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \
|
||||
HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \
|
||||
HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \
|
||||
HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \
|
||||
HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \
|
||||
HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
|
||||
|
||||
@@ -1,35 +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/erpt/erpt_types.hpp>
|
||||
#include <stratosphere/sf/sf_buffer_tags.hpp>
|
||||
|
||||
namespace ams::erpt {
|
||||
|
||||
constexpr inline u32 CategoriesPerMultipleCategoryContext = 0x10;
|
||||
constexpr inline u32 FieldsPerMultipleCategoryContext = CategoriesPerMultipleCategoryContext * 4;
|
||||
|
||||
struct MultipleCategoryContextEntry : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
||||
u32 version;
|
||||
u32 category_count;
|
||||
CategoryId categories[CategoriesPerMultipleCategoryContext];
|
||||
u32 field_counts[CategoriesPerMultipleCategoryContext];
|
||||
u32 array_buf_counts[CategoriesPerMultipleCategoryContext];
|
||||
FieldEntry fields[FieldsPerMultipleCategoryContext];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,234 +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/time/time_posix_time.hpp>
|
||||
#include <stratosphere/erpt/erpt_ids.autogen.hpp>
|
||||
|
||||
namespace ams::erpt {
|
||||
|
||||
#define GENERATE_ENUM(NAME, ID, ...) NAME = ID,
|
||||
|
||||
enum FieldType {
|
||||
AMS_ERPT_FOREACH_FIELD_TYPE(GENERATE_ENUM)
|
||||
FieldType_Count,
|
||||
};
|
||||
|
||||
#undef GENERATE_ENUM
|
||||
|
||||
#define GENERATE_ENUM(NAME, ID, ...) CategoryId_##NAME = ID,
|
||||
|
||||
enum CategoryId {
|
||||
AMS_ERPT_FOREACH_CATEGORY(GENERATE_ENUM)
|
||||
CategoryId_Count,
|
||||
};
|
||||
|
||||
#undef GENERATE_ENUM
|
||||
|
||||
#define GENERATE_ENUM(NAME, ID, ...) FieldId_##NAME = ID,
|
||||
|
||||
enum FieldId {
|
||||
AMS_ERPT_FOREACH_FIELD(GENERATE_ENUM)
|
||||
FieldId_Count,
|
||||
};
|
||||
|
||||
#undef GENERATE_ENUM
|
||||
|
||||
constexpr inline u32 ArrayBufferSizeDefault = 0x100;
|
||||
constexpr inline u32 ArrayBufferSizeMax = 96_KB;
|
||||
constexpr inline u32 ArrayFieldSizeMax = 16_KB - 1;
|
||||
|
||||
enum ReportType {
|
||||
ReportType_Start = 0,
|
||||
|
||||
ReportType_Visible = ReportType_Start,
|
||||
ReportType_Invisible = 1,
|
||||
|
||||
ReportType_End = 2,
|
||||
|
||||
ReportType_Count = ReportType_End,
|
||||
|
||||
ReportType_Any = ReportType_Count,
|
||||
};
|
||||
|
||||
constexpr inline u32 ReportCountMax = 50;
|
||||
constexpr inline u32 AttachmentsPerReportMax = 5;
|
||||
constexpr inline u32 AttachmentCountMax = ReportCountMax * AttachmentsPerReportMax;
|
||||
|
||||
constexpr inline u32 ReportMetaDataSize = 0x20;
|
||||
struct ReportMetaData {
|
||||
u8 user_data[ReportMetaDataSize];
|
||||
};
|
||||
|
||||
|
||||
constexpr inline u32 ReportIdSize = 20;
|
||||
struct ReportId {
|
||||
union {
|
||||
u8 id[ReportIdSize];
|
||||
util::Uuid uuid;
|
||||
#pragma pack(push, 1)
|
||||
struct {
|
||||
u32 time_low;
|
||||
u16 time_mid;
|
||||
u16 time_high_and_version;
|
||||
u8 clock_high;
|
||||
u8 clock_low;
|
||||
u64 node;
|
||||
} uuid_data;
|
||||
#pragma pack(pop)
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ReportId) == ReportIdSize);
|
||||
|
||||
inline bool operator==(const ReportId &lhs, const ReportId &rhs) {
|
||||
return std::memcmp(lhs.id, rhs.id, sizeof(lhs.uuid)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const ReportId &lhs, const ReportId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
struct ReportFlag {
|
||||
using Transmitted = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>::Flag<0>;
|
||||
using HasAttachment = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>::Flag<1>;
|
||||
};
|
||||
|
||||
using ReportFlagSet = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>;
|
||||
static_assert(std::is_pod<ReportFlagSet>::value);
|
||||
static_assert(sizeof(ReportFlagSet) == sizeof(u32));
|
||||
|
||||
struct ReportInfo {
|
||||
ReportType type;
|
||||
ReportId id;
|
||||
ReportMetaData meta_data;
|
||||
ReportFlagSet flags;
|
||||
time::PosixTime timestamp_user;
|
||||
time::PosixTime timestamp_network;
|
||||
s64 report_size;
|
||||
u64 reserved[3];
|
||||
};
|
||||
|
||||
struct ReportList {
|
||||
u32 report_count;
|
||||
ReportInfo reports[ReportCountMax];
|
||||
};
|
||||
|
||||
constexpr inline u32 AttachmentIdSize = 20;
|
||||
struct AttachmentId {
|
||||
union {
|
||||
u8 id[AttachmentIdSize];
|
||||
util::Uuid uuid;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(AttachmentId) == AttachmentIdSize);
|
||||
|
||||
inline bool operator==(const AttachmentId &lhs, const AttachmentId &rhs) {
|
||||
return std::memcmp(lhs.id, rhs.id, sizeof(lhs.uuid)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const AttachmentId &lhs, const AttachmentId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
struct AttachmentFlag {
|
||||
using HasOwner = util::BitFlagSet<BITSIZEOF(u32), AttachmentFlag>::Flag<1>;
|
||||
};
|
||||
|
||||
using AttachmentFlagSet = util::BitFlagSet<BITSIZEOF(u32), AttachmentFlag>;
|
||||
static_assert(std::is_pod<AttachmentFlagSet>::value);
|
||||
static_assert(sizeof(AttachmentFlagSet) == sizeof(u32));
|
||||
|
||||
constexpr inline u32 AttachmentNameSizeMax = 0x20;
|
||||
struct AttachmentInfo {
|
||||
ReportId owner_report_id;
|
||||
AttachmentId attachment_id;
|
||||
AttachmentFlagSet flags;
|
||||
s64 attachment_size;
|
||||
char attachment_name[AttachmentNameSizeMax];
|
||||
};
|
||||
|
||||
struct AttachmentList {
|
||||
u32 attachment_count;
|
||||
AttachmentInfo attachments[AttachmentsPerReportMax];
|
||||
};
|
||||
|
||||
constexpr inline u32 AttachmentSizeMax = 512_KB;
|
||||
|
||||
struct FieldEntry {
|
||||
FieldId id;
|
||||
FieldType type;
|
||||
union {
|
||||
u64 value_u64;
|
||||
u32 value_u32;
|
||||
u16 value_u16;
|
||||
u8 value_u8;
|
||||
s64 value_i64;
|
||||
s32 value_i32;
|
||||
s16 value_i16;
|
||||
s8 value_i8;
|
||||
bool value_bool;
|
||||
struct {
|
||||
u32 start_idx;
|
||||
u32 size;
|
||||
} value_array;
|
||||
};
|
||||
};
|
||||
|
||||
constexpr inline u32 FieldsPerContext = 20;
|
||||
struct ContextEntry {
|
||||
u32 version;
|
||||
u32 field_count;
|
||||
CategoryId category;
|
||||
FieldEntry fields[FieldsPerContext];
|
||||
u8 *array_buffer;
|
||||
u32 array_free_count;
|
||||
u32 array_buffer_size;
|
||||
};
|
||||
|
||||
struct StorageUsageStatistics {
|
||||
util::Uuid journal_uuid;
|
||||
u32 used_storage_size;
|
||||
s64 max_report_size;
|
||||
u32 report_count[ReportType_Count];
|
||||
u32 transmitted_count[ReportType_Count];
|
||||
u32 untransmitted_count[ReportType_Count];
|
||||
};
|
||||
|
||||
/* https://github.com/msgpack/msgpack/blob/master/spec.md#overview */
|
||||
enum class ValueTypeTag {
|
||||
FixMap = 0x80,
|
||||
FixArray = 0x90,
|
||||
FixStr = 0xA0,
|
||||
False = 0xC2,
|
||||
True = 0xC3,
|
||||
Bin8 = 0xC4,
|
||||
Bin16 = 0xC5,
|
||||
U8 = 0xCC,
|
||||
U16 = 0xCD,
|
||||
U32 = 0xCE,
|
||||
U64 = 0xCF,
|
||||
I8 = 0xD0,
|
||||
I16 = 0xD1,
|
||||
I32 = 0xD2,
|
||||
I64 = 0xD3,
|
||||
Str8 = 0xD9,
|
||||
Str16 = 0xDA,
|
||||
Array16 = 0xDC,
|
||||
Map16 = 0xDE,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,51 +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 <vapours.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
|
||||
namespace ams::erpt::sf {
|
||||
|
||||
class IAttachment : public ams::sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
Open = 0,
|
||||
Read = 1,
|
||||
SetFlags = 2,
|
||||
GetFlags = 3,
|
||||
Close = 4,
|
||||
GetSize = 5,
|
||||
};
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result Open(const AttachmentId &attachment_id) = 0;
|
||||
virtual Result Read(ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buffer) = 0;
|
||||
virtual Result SetFlags(AttachmentFlagSet flags) = 0;
|
||||
virtual Result GetFlags(ams::sf::Out<AttachmentFlagSet> out) = 0;
|
||||
virtual Result Close() = 0;
|
||||
virtual Result GetSize(ams::sf::Out<s64> out) = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(Open),
|
||||
MAKE_SERVICE_COMMAND_META(Read),
|
||||
MAKE_SERVICE_COMMAND_META(SetFlags),
|
||||
MAKE_SERVICE_COMMAND_META(GetFlags),
|
||||
MAKE_SERVICE_COMMAND_META(Close),
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,69 +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 <vapours.hpp>
|
||||
#include <stratosphere/sf.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
#include <stratosphere/erpt/erpt_multiple_category_context.hpp>
|
||||
#include <stratosphere/time/time_steady_clock_time_point.hpp>
|
||||
|
||||
namespace ams::erpt::sf {
|
||||
|
||||
class IContext : public ams::sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
SubmitContext = 0,
|
||||
CreateReport = 1,
|
||||
SetInitialLaunchSettingsCompletionTime = 2,
|
||||
ClearInitialLaunchSettingsCompletionTime = 3,
|
||||
UpdatePowerOnTime = 4,
|
||||
UpdateAwakeTime = 5,
|
||||
SubmitMultipleCategoryContext = 6,
|
||||
UpdateApplicationLaunchTime = 7,
|
||||
ClearApplicationLaunchTime = 8,
|
||||
SubmitAttachment = 9,
|
||||
CreateReportWithAttachments = 10,
|
||||
};
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result SubmitContext(const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer) = 0;
|
||||
virtual Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer) = 0;
|
||||
virtual Result SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time_point) = 0;
|
||||
virtual Result ClearInitialLaunchSettingsCompletionTime() = 0;
|
||||
virtual Result UpdatePowerOnTime() = 0;
|
||||
virtual Result UpdateAwakeTime() = 0;
|
||||
virtual Result SubmitMultipleCategoryContext(const MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer) = 0;
|
||||
virtual Result UpdateApplicationLaunchTime() = 0;
|
||||
virtual Result ClearApplicationLaunchTime() = 0;
|
||||
virtual Result SubmitAttachment(ams::sf::Out<AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) = 0;
|
||||
virtual Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer) = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SubmitContext),
|
||||
MAKE_SERVICE_COMMAND_META(CreateReport),
|
||||
MAKE_SERVICE_COMMAND_META(SetInitialLaunchSettingsCompletionTime, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ClearInitialLaunchSettingsCompletionTime, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UpdatePowerOnTime, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UpdateAwakeTime, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(SubmitMultipleCategoryContext, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UpdateApplicationLaunchTime, hos::Version_6_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ClearApplicationLaunchTime, hos::Version_6_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(SubmitAttachment, hos::Version_8_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(CreateReportWithAttachments, hos::Version_8_0_0),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,51 +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 <vapours.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
|
||||
namespace ams::erpt::sf {
|
||||
|
||||
class IManager : public ams::sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
GetReportList = 0,
|
||||
GetEvent = 1,
|
||||
CleanupReports = 2,
|
||||
DeleteReport = 3,
|
||||
GetStorageUsageStatistics = 4,
|
||||
GetAttachmentList = 5,
|
||||
};
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter) = 0;
|
||||
virtual Result GetEvent(ams::sf::OutCopyHandle out) = 0;
|
||||
virtual Result CleanupReports() = 0;
|
||||
virtual Result DeleteReport(const ReportId &report_id) = 0;
|
||||
virtual Result GetStorageUsageStatistics(ams::sf::Out<StorageUsageStatistics> out) = 0;
|
||||
virtual Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id) = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetReportList),
|
||||
MAKE_SERVICE_COMMAND_META(GetEvent),
|
||||
MAKE_SERVICE_COMMAND_META(CleanupReports, hos::Version_4_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DeleteReport, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetStorageUsageStatistics, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetAttachmentList, hos::Version_8_0_0),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,51 +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 <vapours.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
|
||||
namespace ams::erpt::sf {
|
||||
|
||||
class IReport : public ams::sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
Open = 0,
|
||||
Read = 1,
|
||||
SetFlags = 2,
|
||||
GetFlags = 3,
|
||||
Close = 4,
|
||||
GetSize = 5,
|
||||
};
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result Open(const ReportId &report_id) = 0;
|
||||
virtual Result Read(ams::sf::Out<u32> out_count, const ams::sf::OutBuffer &out_buffer) = 0;
|
||||
virtual Result SetFlags(ReportFlagSet flags) = 0;
|
||||
virtual Result GetFlags(ams::sf::Out<ReportFlagSet> out) = 0;
|
||||
virtual Result Close() = 0;
|
||||
virtual Result GetSize(ams::sf::Out<s64> out) = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(Open),
|
||||
MAKE_SERVICE_COMMAND_META(Read),
|
||||
MAKE_SERVICE_COMMAND_META(SetFlags),
|
||||
MAKE_SERVICE_COMMAND_META(GetFlags),
|
||||
MAKE_SERVICE_COMMAND_META(Close),
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,45 +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 <vapours.hpp>
|
||||
#include <stratosphere/erpt/erpt_types.hpp>
|
||||
#include <stratosphere/erpt/sf/erpt_sf_i_report.hpp>
|
||||
#include <stratosphere/erpt/sf/erpt_sf_i_manager.hpp>
|
||||
#include <stratosphere/erpt/sf/erpt_sf_i_attachment.hpp>
|
||||
|
||||
namespace ams::erpt::sf {
|
||||
|
||||
class ISession : public ams::sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
OpenReport = 0,
|
||||
OpenManager = 1,
|
||||
OpenAttachment = 2,
|
||||
};
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result OpenReport(ams::sf::Out<std::shared_ptr<erpt::sf::IReport>> out) = 0;
|
||||
virtual Result OpenManager(ams::sf::Out<std::shared_ptr<erpt::sf::IManager>> out) = 0;
|
||||
virtual Result OpenAttachment(ams::sf::Out<std::shared_ptr<erpt::sf::IAttachment>> out) = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(OpenReport),
|
||||
MAKE_SERVICE_COMMAND_META(OpenManager),
|
||||
MAKE_SERVICE_COMMAND_META(OpenAttachment, hos::Version_8_0_0),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,33 +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::erpt::srv {
|
||||
|
||||
Result Initialize(u8 *mem, size_t mem_size);
|
||||
Result InitializeAndStartService();
|
||||
|
||||
Result SetSerialNumberAndOsVersion(const char *sn, u32 sn_len, const char *os, u32 os_len, const char *os_priv, u32 os_priv_len);
|
||||
Result SetProductModel(const char *model, u32 model_len);
|
||||
Result SetRegionSetting(const char *region, u32 region_len);
|
||||
|
||||
/* Atmosphere extension. */
|
||||
Result SetRedirectNewReportsToSdCard(bool redirect);
|
||||
|
||||
void Wait();
|
||||
|
||||
}
|
||||
@@ -1,86 +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/erpt/erpt_ids.autogen.hpp>
|
||||
|
||||
namespace ams::erpt::srv {
|
||||
|
||||
constexpr inline const char ReportOnSdStoragePath[] = "ersd";
|
||||
|
||||
constexpr inline const char ReportStoragePath[] = "save";
|
||||
constexpr inline const char JournalFileName[] = "save:/journal";
|
||||
|
||||
constexpr size_t ReportFileNameLength = 64;
|
||||
constexpr size_t AttachmentFileNameLength = 64;
|
||||
constexpr size_t MaxFieldStringSize = 64;
|
||||
|
||||
struct ReportFileName {
|
||||
char name[ReportFileNameLength];
|
||||
};
|
||||
|
||||
struct AttachmentFileName {
|
||||
char name[AttachmentFileNameLength];
|
||||
};
|
||||
|
||||
enum FieldFlag : u8 {
|
||||
FieldFlag_None = 0,
|
||||
FieldFlag_Encrypt = 1,
|
||||
};
|
||||
|
||||
#define STRINGIZE_HANDLER(NAME, ...) #NAME,
|
||||
constexpr inline const char * const FieldString[] = {
|
||||
AMS_ERPT_FOREACH_FIELD(STRINGIZE_HANDLER)
|
||||
};
|
||||
|
||||
constexpr inline const char * const CategoryString[] = {
|
||||
AMS_ERPT_FOREACH_CATEGORY(STRINGIZE_HANDLER)
|
||||
};
|
||||
|
||||
constexpr inline const char * const TypeString[] = {
|
||||
AMS_ERPT_FOREACH_FIELD_TYPE(STRINGIZE_HANDLER)
|
||||
};
|
||||
#undef STRINGIZE_HANDLER
|
||||
|
||||
#define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = CategoryId_##CATEGORY,
|
||||
constexpr inline const CategoryId FieldToCategoryMap[] = {
|
||||
AMS_ERPT_FOREACH_FIELD(GET_FIELD_CATEGORY)
|
||||
};
|
||||
#undef GET_FIELD_CATEGORY
|
||||
|
||||
#define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = TYPE,
|
||||
constexpr inline const FieldType FieldToTypeMap[] = {
|
||||
AMS_ERPT_FOREACH_FIELD(GET_FIELD_TYPE)
|
||||
};
|
||||
#undef GET_FIELD_TYPE
|
||||
|
||||
#define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = FLAG,
|
||||
constexpr inline const FieldFlag FieldToFlagMap[] = {
|
||||
AMS_ERPT_FOREACH_FIELD(GET_FIELD_FLAG)
|
||||
};
|
||||
#undef GET_FIELD_FLAG
|
||||
|
||||
constexpr inline ReportFlagSet MakeNoReportFlags() {
|
||||
return util::MakeBitFlagSet<32, ReportFlag>();
|
||||
}
|
||||
|
||||
constexpr inline AttachmentFlagSet MakeNoAttachmentFlags() {
|
||||
return util::MakeBitFlagSet<32, AttachmentFlag>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -324,20 +324,28 @@ namespace ams::fatal {
|
||||
bool is_creport;
|
||||
CpuContext cpu_ctx;
|
||||
bool generate_error_report;
|
||||
os::Event *erpt_event;
|
||||
os::Event *battery_event;
|
||||
Event erpt_event;
|
||||
Event battery_event;
|
||||
size_t stack_dump_size;
|
||||
u64 stack_dump_base;
|
||||
u8 stack_dump[0x100];
|
||||
u64 tls_address;
|
||||
u8 tls_dump[0x100];
|
||||
|
||||
ThrowContext(os::Event *erpt, os::Event *bat)
|
||||
: result(ResultSuccess()), program_id(), proc_name(), is_creport(), cpu_ctx(), generate_error_report(),
|
||||
erpt_event(erpt), battery_event(bat),
|
||||
stack_dump_size(), stack_dump_base(), stack_dump(), tls_address(), tls_dump()
|
||||
{
|
||||
/* ... */
|
||||
void ClearState() {
|
||||
this->result = ResultSuccess();
|
||||
this->program_id = ncm::ProgramId::Invalid;
|
||||
std::memset(this->proc_name, 0, sizeof(this->proc_name));
|
||||
this->is_creport = false;
|
||||
std::memset(&this->cpu_ctx, 0, sizeof(this->cpu_ctx));
|
||||
this->generate_error_report = false;
|
||||
std::memset(&this->erpt_event, 0, sizeof(this->erpt_event));
|
||||
std::memset(&this->battery_event, 0, sizeof(this->battery_event));
|
||||
this->stack_dump_size = 0;
|
||||
this->stack_dump_base = 0;
|
||||
std::memset(this->stack_dump, 0, sizeof(this->stack_dump));
|
||||
this->tls_address = 0;
|
||||
std::memset(this->tls_dump, 0, sizeof(this->tls_dump));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,17 +19,9 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct CodeInfo {
|
||||
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(const char *name, const char *path, ncm::ProgramId program_id);
|
||||
|
||||
Result MountCode(CodeInfo *out, 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);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@@ -115,11 +115,12 @@ namespace ams::fs {
|
||||
return this->GetImpl(std::addressof(pos), out, key, hash_key, aux, aux_size);
|
||||
}
|
||||
|
||||
void FindOpen(FindIndex *out) const {
|
||||
Result FindOpen(FindIndex *out) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
out->ind = static_cast<BucketIndex>(-1);
|
||||
out->pos = InvalidPosition;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindNext(Key *out_key, Value *out_val, FindIndex *find) {
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ams::fs {
|
||||
s64 size;
|
||||
os::Mutex mutex;
|
||||
public:
|
||||
constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : handle(handle), close_file(close_file), size(InvalidSize), mutex(false) { /* ... */ }
|
||||
constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : handle(handle), close_file(close_file), size(InvalidSize), mutex() { /* ... */ }
|
||||
constexpr explicit FileHandleStorage(FileHandle handle) : FileHandleStorage(handle, false) { /* ... */ }
|
||||
|
||||
virtual ~FileHandleStorage() override {
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
namespace ams::fs {
|
||||
|
||||
struct QueryRangeInfo {
|
||||
s32 aes_ctr_key_type;
|
||||
s32 speed_emulation_type;
|
||||
u8 reserved[0x38];
|
||||
u32 aes_ctr_key_type;
|
||||
u32 speed_emulation_type;
|
||||
u32 reserved[0x38 / sizeof(u32)];
|
||||
|
||||
void Clear() {
|
||||
this->aes_ctr_key_type = 0;
|
||||
@@ -45,8 +45,4 @@ namespace ams::fs {
|
||||
|
||||
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size);
|
||||
|
||||
enum class AesCtrKeyTypeFlag : s32 {
|
||||
InternalKeyForSoftwareAes = (1 << 0),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace ams::fs {
|
||||
private:
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fsa::IFile> *out_file, const char *path, OpenMode mode) override final {
|
||||
/* Only allow opening files with mode = read. */
|
||||
R_UNLESS((mode & fs::OpenMode_All) == fs::OpenMode_Read, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & fs::OpenMode_All) == fs::OpenMode_Read, fs::ResultInvalidArgument());
|
||||
|
||||
std::unique_ptr<fsa::IFile> base_file;
|
||||
R_TRY(this->base_fs->OpenFile(std::addressof(base_file), path, mode));
|
||||
|
||||
@@ -19,26 +19,12 @@
|
||||
namespace ams::fs {
|
||||
|
||||
union RightsId {
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
};
|
||||
static_assert(sizeof(RightsId) == 0x10);
|
||||
static_assert(std::is_pod<RightsId>::value);
|
||||
|
||||
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const RightsId &lhs, const RightsId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) < 0;
|
||||
}
|
||||
|
||||
constexpr inline RightsId InvalidRightsId = {};
|
||||
|
||||
/* Rights ID API */
|
||||
Result GetRightsId(RightsId *out, const char *path);
|
||||
Result GetRightsId(RightsId *out, u8 *out_key_generation, const char *path);
|
||||
|
||||
@@ -26,9 +26,4 @@ namespace ams::fs {
|
||||
Result GetSaveDataFlags(u32 *out, SaveDataSpaceId space_id, SaveDataId id);
|
||||
Result SetSaveDataFlags(SaveDataId id, SaveDataSpaceId space_id, u32 flags);
|
||||
|
||||
Result GetSaveDataAvailableSize(s64 *out, SaveDataId id);
|
||||
Result GetSaveDataJournalSize(s64 *out, SaveDataId id);
|
||||
|
||||
Result ExtendSaveData(SaveDataSpaceId space_id, SaveDataId id, s64 available_size, s64 journal_size);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,4 @@ namespace ams::fs {
|
||||
|
||||
Result MountSdCard(const char *name);
|
||||
|
||||
Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name);
|
||||
|
||||
}
|
||||
|
||||
@@ -83,16 +83,16 @@ namespace ams::fs::fsa {
|
||||
Result OpenFile(std::unique_ptr<IFile> *out_file, const char *path, OpenMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenMode_ReadWrite) != 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & ~OpenMode_All) == 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & OpenMode_ReadWrite) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~OpenMode_All) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenFileImpl(out_file, path, mode);
|
||||
}
|
||||
|
||||
Result OpenDirectory(std::unique_ptr<IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenDirectoryMode_All) != 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & ~(OpenDirectoryMode_All | OpenDirectoryMode_NotRequireFileSize)) == 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & OpenDirectoryMode_All) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~(OpenDirectoryMode_All | OpenDirectoryMode_NotRequireFileSize)) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenDirectoryImpl(out_dir, path, mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace ams::fssrv::impl {
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
|
||||
/* 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),
|
||||
|
||||
/* 3.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_300),
|
||||
MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_300),
|
||||
|
||||
/* 4.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_4_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_400),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace ams::fssrv::impl {
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
|
||||
/* 4.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_4_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -15,19 +15,11 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere/fssystem/fssystem_utility.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_meta.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_path_tool.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_thread_priority_changer.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_aes_ctr_storage.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_aes_xts_storage.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_subdirectory_filesystem.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_directory_redirection_filesystem.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_directory_savedata_filesystem.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_romfs_file_system.hpp>
|
||||
#include <stratosphere/fssystem/buffers/fssystem_buffer_manager_utils.hpp>
|
||||
#include <stratosphere/fssystem/buffers/fssystem_file_system_buddy_heap.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_pooled_buffer.hpp>
|
||||
#include "fssystem/fssystem_utility.hpp"
|
||||
#include "fssystem/fssystem_external_code.hpp"
|
||||
#include "fssystem/fssystem_partition_file_system.hpp"
|
||||
#include "fssystem/fssystem_partition_file_system_meta.hpp"
|
||||
#include "fssystem/fssystem_path_tool.hpp"
|
||||
#include "fssystem/fssystem_subdirectory_filesystem.hpp"
|
||||
#include "fssystem/fssystem_directory_redirection_filesystem.hpp"
|
||||
#include "fssystem/fssystem_directory_savedata_filesystem.hpp"
|
||||
|
||||
@@ -1,90 +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>
|
||||
|
||||
namespace ams::fssystem::buffers {
|
||||
|
||||
namespace impl {
|
||||
|
||||
constexpr inline auto RetryWait = TimeSpan::FromMilliSeconds(10);
|
||||
|
||||
}
|
||||
|
||||
template<typename F, typename OnFailure>
|
||||
Result DoContinuouslyUntilBufferIsAllocated(F f, OnFailure on_failure, const char *function_name) {
|
||||
constexpr auto BufferAllocationRetryLogCountMax = 10;
|
||||
constexpr auto BufferAllocationRetryLogInterval = 100;
|
||||
for (auto count = 1; true; count++) {
|
||||
R_TRY_CATCH(f()) {
|
||||
R_CATCH(fs::ResultBufferAllocationFailed) {
|
||||
if ((1 <= count && count <= BufferAllocationRetryLogCountMax) || ((count % BufferAllocationRetryLogInterval) == 0)) {
|
||||
/* TODO: Log */
|
||||
}
|
||||
R_TRY(on_failure());
|
||||
|
||||
/* TODO: os::SleepThread */
|
||||
svc::SleepThread(impl::RetryWait.GetNanoSeconds());
|
||||
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
Result DoContinuouslyUntilBufferIsAllocated(F f, const char *function_name) {
|
||||
R_TRY(DoContinuouslyUntilBufferIsAllocated(f, []() ALWAYS_INLINE_LAMBDA { return ResultSuccess(); }, function_name));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
class BufferManagerContext {
|
||||
private:
|
||||
bool needs_blocking;
|
||||
public:
|
||||
constexpr BufferManagerContext() : needs_blocking(false) { /* ... */ }
|
||||
public:
|
||||
bool IsNeedBlocking() const { return this->needs_blocking; }
|
||||
|
||||
void SetNeedBlocking(bool need) { this->needs_blocking = need; }
|
||||
};
|
||||
|
||||
void RegisterBufferManagerContext(const BufferManagerContext *context);
|
||||
BufferManagerContext *GetBufferManagerContext();
|
||||
void EnableBlockingBufferManagerAllocation();
|
||||
|
||||
class ScopedBufferManagerContextRegistration {
|
||||
private:
|
||||
BufferManagerContext cur_context;
|
||||
const BufferManagerContext *old_context;
|
||||
public:
|
||||
ALWAYS_INLINE explicit ScopedBufferManagerContextRegistration() {
|
||||
this->old_context = GetBufferManagerContext();
|
||||
if (this->old_context != nullptr) {
|
||||
this->cur_context = *this->old_context;
|
||||
}
|
||||
RegisterBufferManagerContext(std::addressof(this->cur_context));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~ScopedBufferManagerContextRegistration() {
|
||||
RegisterBufferManagerContext(this->old_context);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,189 +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/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class FileSystemBuddyHeap {
|
||||
NON_COPYABLE(FileSystemBuddyHeap);
|
||||
NON_MOVEABLE(FileSystemBuddyHeap);
|
||||
public:
|
||||
static constexpr size_t BufferAlignment = sizeof(void *);
|
||||
static constexpr size_t BlockSizeMin = 2 * sizeof(void *);
|
||||
static constexpr s32 OrderUpperLimit = BITSIZEOF(s32) - 1;
|
||||
private:
|
||||
class PageList;
|
||||
|
||||
struct PageEntry { PageEntry *next; };
|
||||
static_assert(std::is_pod<PageEntry>::value);
|
||||
static_assert(sizeof(PageEntry) <= BlockSizeMin);
|
||||
|
||||
class PageList : public ::ams::fs::impl::Newable {
|
||||
NON_COPYABLE(PageList);
|
||||
NON_MOVEABLE(PageList);
|
||||
private:
|
||||
PageEntry *first_page_entry;
|
||||
PageEntry *last_page_entry;
|
||||
s32 entry_count;
|
||||
public:
|
||||
constexpr PageList() : first_page_entry(), last_page_entry(), entry_count() { /* ... */ }
|
||||
|
||||
constexpr bool IsEmpty() const { return this->entry_count == 0; }
|
||||
constexpr s32 GetSize() const { return this->entry_count; }
|
||||
|
||||
constexpr const PageEntry *GetFront() const { return this->first_page_entry; }
|
||||
public:
|
||||
PageEntry *PopFront();
|
||||
void PushBack(PageEntry *page_entry);
|
||||
bool Remove(PageEntry *page_entry);
|
||||
};
|
||||
private:
|
||||
size_t block_size;
|
||||
s32 order_max;
|
||||
uintptr_t heap_start;
|
||||
size_t heap_size;
|
||||
|
||||
PageList *free_lists;
|
||||
size_t total_free_size;
|
||||
PageList *external_free_lists;
|
||||
std::unique_ptr<PageList[]> internal_free_lists;
|
||||
public:
|
||||
static constexpr s32 GetBlockCountFromOrder(s32 order) {
|
||||
AMS_ASSERT(0 <= order);
|
||||
AMS_ASSERT(order < OrderUpperLimit);
|
||||
return (1 << order);
|
||||
}
|
||||
|
||||
static constexpr size_t QueryWorkBufferSize(s32 order_max) {
|
||||
AMS_ASSERT(0 < order_max && order_max < OrderUpperLimit);
|
||||
return util::AlignUp(sizeof(PageList) * (order_max + 1) + alignof(PageList), alignof(u64));
|
||||
}
|
||||
|
||||
static constexpr s32 QueryOrderMax(size_t size, size_t block_size) {
|
||||
AMS_ASSERT(size >= block_size);
|
||||
AMS_ASSERT(block_size >= BlockSizeMin);
|
||||
AMS_ASSERT(util::IsPowerOfTwo(block_size));
|
||||
const auto block_count = static_cast<s32>(util::AlignUp(size, block_size) / block_size);
|
||||
for (auto order = 1; true; order++) {
|
||||
if (block_count <= GetBlockCountFromOrder(order)) {
|
||||
return order;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr FileSystemBuddyHeap() : block_size(), order_max(), heap_start(), heap_size(), free_lists(), total_free_size(), external_free_lists(), internal_free_lists() { /* ... */ }
|
||||
|
||||
Result Initialize(uintptr_t address, size_t size, size_t block_size, s32 order_max);
|
||||
|
||||
Result Initialize(uintptr_t address, size_t size, size_t block_size) {
|
||||
return this->Initialize(address, size, block_size, QueryOrderMax(size, block_size));
|
||||
}
|
||||
|
||||
Result Initialize(uintptr_t address, size_t size, size_t block_size, s32 order_max, void *work, size_t work_size) {
|
||||
AMS_ASSERT(work_size >= QueryWorkBufferSize(order_max));
|
||||
const auto aligned_work = util::AlignUp(reinterpret_cast<uintptr_t>(work), alignof(PageList));
|
||||
this->external_free_lists = reinterpret_cast<PageList *>(aligned_work);
|
||||
return this->Initialize(address, size, block_size, order_max);
|
||||
}
|
||||
|
||||
Result Initialize(uintptr_t address, size_t size, size_t block_size, void *work, size_t work_size) {
|
||||
return this->Initialize(address, size, block_size, QueryOrderMax(size, block_size), work, work_size);
|
||||
}
|
||||
|
||||
void Finalize();
|
||||
|
||||
void *AllocateByOrder(s32 order);
|
||||
void Free(void *ptr, s32 order);
|
||||
|
||||
size_t GetTotalFreeSize() const;
|
||||
size_t GetAllocatableSizeMax() const;
|
||||
void Dump() const;
|
||||
|
||||
s32 GetOrderFromBytes(size_t size) const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
return this->GetOrderFromBlockCount(this->GetBlockCountFromSize(size));
|
||||
}
|
||||
|
||||
size_t GetBytesFromOrder(s32 order) const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
AMS_ASSERT(0 <= order);
|
||||
AMS_ASSERT(order < this->GetOrderMax());
|
||||
return (this->GetBlockSize() << order);
|
||||
}
|
||||
|
||||
s32 GetOrderMax() const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
return this->order_max;
|
||||
}
|
||||
|
||||
size_t GetBlockSize() const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
return this->block_size;
|
||||
}
|
||||
|
||||
s32 GetPageBlockCountMax() const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
return 1 << this->GetOrderMax();
|
||||
}
|
||||
|
||||
size_t GetPageSizeMax() const {
|
||||
AMS_ASSERT(this->free_lists != nullptr);
|
||||
return this->GetPageBlockCountMax() * this->GetBlockSize();
|
||||
}
|
||||
private:
|
||||
void DivideBuddies(PageEntry *page_entry, s32 required_order, s32 chosen_order);
|
||||
void JoinBuddies(PageEntry *page_entry, s32 order);
|
||||
PageEntry *GetBuddy(PageEntry *page_entry, s32 order);
|
||||
PageEntry *GetFreePageEntry(s32 order);
|
||||
|
||||
s32 GetOrderFromBlockCount(s32 block_count) const;
|
||||
|
||||
s32 GetBlockCountFromSize(size_t size) const {
|
||||
const size_t bsize = this->GetBlockSize();
|
||||
return static_cast<s32>(util::AlignUp(size, bsize) / bsize);
|
||||
}
|
||||
|
||||
uintptr_t GetAddressFromPageEntry(const PageEntry &page_entry) const {
|
||||
const uintptr_t address = reinterpret_cast<uintptr_t>(std::addressof(page_entry));
|
||||
AMS_ASSERT(this->heap_start <= address);
|
||||
AMS_ASSERT(address < this->heap_start + this->heap_size);
|
||||
AMS_ASSERT(util::IsAligned(address - this->heap_start, this->GetBlockSize()));
|
||||
return address;
|
||||
}
|
||||
|
||||
PageEntry *GetPageEntryFromAddress(uintptr_t address) const {
|
||||
AMS_ASSERT(this->heap_start <= address);
|
||||
AMS_ASSERT(address < this->heap_start + this->heap_size);
|
||||
return reinterpret_cast<PageEntry *>(this->heap_start + util::AlignDown(address - this->heap_start, this->GetBlockSize()));
|
||||
}
|
||||
|
||||
s32 GetIndexFromPageEntry(const PageEntry &page_entry) const {
|
||||
const uintptr_t address = reinterpret_cast<uintptr_t>(std::addressof(page_entry));
|
||||
AMS_ASSERT(this->heap_start <= address);
|
||||
AMS_ASSERT(address < this->heap_start + this->heap_size);
|
||||
AMS_ASSERT(util::IsAligned(address - this->heap_start, this->GetBlockSize()));
|
||||
return static_cast<s32>((address - this->heap_start) / this->GetBlockSize());
|
||||
}
|
||||
|
||||
bool IsAlignedToOrder(const PageEntry *page_entry, s32 order) const {
|
||||
return util::IsAligned(GetIndexFromPageEntry(*page_entry), GetBlockCountFromOrder(order));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -1,50 +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/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class AesCtrStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||
NON_COPYABLE(AesCtrStorage);
|
||||
NON_MOVEABLE(AesCtrStorage);
|
||||
public:
|
||||
static constexpr size_t BlockSize = crypto::Aes128CtrEncryptor::BlockSize;
|
||||
static constexpr size_t KeySize = crypto::Aes128CtrEncryptor::KeySize;
|
||||
static constexpr size_t IvSize = crypto::Aes128CtrEncryptor::IvSize;
|
||||
private:
|
||||
IStorage * const base_storage;
|
||||
char key[KeySize];
|
||||
char iv[IvSize];
|
||||
public:
|
||||
static void MakeIv(void *dst, size_t dst_size, u64 upper, s64 offset);
|
||||
public:
|
||||
AesCtrStorage(IStorage *base, const void *key, size_t key_size, const void *iv, size_t iv_size);
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
|
||||
virtual Result Flush() override;
|
||||
|
||||
virtual Result SetSize(s64 size) override;
|
||||
virtual Result GetSize(s64 *out) override;
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,51 +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/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/os.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class AesXtsStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||
NON_COPYABLE(AesXtsStorage);
|
||||
NON_MOVEABLE(AesXtsStorage);
|
||||
public:
|
||||
static constexpr size_t AesBlockSize = crypto::Aes128XtsEncryptor::BlockSize;
|
||||
static constexpr size_t KeySize = crypto::Aes128XtsEncryptor::KeySize;
|
||||
static constexpr size_t IvSize = crypto::Aes128XtsEncryptor::IvSize;
|
||||
private:
|
||||
IStorage * const base_storage;
|
||||
char key[2][KeySize];
|
||||
char iv[IvSize];
|
||||
const size_t block_size;
|
||||
os::Mutex mutex;
|
||||
public:
|
||||
AesXtsStorage(IStorage *base, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size);
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
|
||||
virtual Result Flush() override;
|
||||
|
||||
virtual Result SetSize(s64 size) override;
|
||||
virtual Result GetSize(s64 *out) override;
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,684 +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/fssystem/fssystem_dbm_rom_types.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_dbm_rom_path_tool.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_dbm_rom_key_value_storage.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
template<typename DBS, typename DES, typename FBS, typename FES>
|
||||
class HierarchicalRomFileTable {
|
||||
private:
|
||||
using DirectoryBucketStorage = DBS;
|
||||
using DirectoryEntryStorage = DES;
|
||||
using FileBucketStorage = FBS;
|
||||
using FileEntryStorage = FES;
|
||||
public:
|
||||
using Position = u32;
|
||||
|
||||
struct FindPosition {
|
||||
Position next_dir;
|
||||
Position next_file;
|
||||
};
|
||||
static_assert(std::is_pod<FindPosition>::value);
|
||||
|
||||
using DirectoryInfo = RomDirectoryInfo;
|
||||
using FileInfo = RomFileInfo;
|
||||
|
||||
static constexpr RomFileId ConvertToFileId(Position pos) {
|
||||
return static_cast<RomFileId>(pos);
|
||||
}
|
||||
private:
|
||||
static constexpr inline Position InvalidPosition = ~Position();
|
||||
static constexpr inline Position RootPosition = 0;
|
||||
static constexpr inline size_t ReservedDirectoryCount = 1;
|
||||
|
||||
static constexpr RomDirectoryId ConvertToDirectoryId(Position pos) {
|
||||
return static_cast<RomDirectoryId>(pos);
|
||||
}
|
||||
|
||||
static constexpr Position ConvertToPosition(RomDirectoryId id) {
|
||||
return static_cast<Position>(id);
|
||||
}
|
||||
|
||||
static_assert(std::is_same<RomDirectoryId, RomFileId>::value);
|
||||
|
||||
struct RomDirectoryEntry {
|
||||
Position next;
|
||||
Position dir;
|
||||
Position file;
|
||||
};
|
||||
static_assert(std::is_pod<RomDirectoryEntry>::value);
|
||||
|
||||
struct RomFileEntry {
|
||||
Position next;
|
||||
FileInfo info;
|
||||
};
|
||||
static_assert(std::is_pod<RomFileEntry>::value);
|
||||
|
||||
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
|
||||
|
||||
template<typename BucketStorageType, typename EntryStorageType, typename ImplKeyType, typename ClientKeyType, typename ValueType>
|
||||
class EntryMapTable : public RomKeyValueStorage<BucketStorageType, EntryStorageType, ImplKeyType, ValueType, MaxKeyLength> {
|
||||
private:
|
||||
using BucketStorage = BucketStorageType;
|
||||
using EntryStorage = EntryStorageType;
|
||||
public:
|
||||
using ImplKey = ImplKeyType;
|
||||
using ClientKey = ClientKeyType;
|
||||
using Value = ValueType;
|
||||
using Position = HierarchicalRomFileTable::Position;
|
||||
using Base = RomKeyValueStorage<BucketStorageType, EntryStorageType, ImplKeyType, ValueType, MaxKeyLength>;
|
||||
public:
|
||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
||||
return Base::AddImpl(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
|
||||
}
|
||||
|
||||
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) const {
|
||||
return Base::GetImpl(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
|
||||
}
|
||||
|
||||
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) const {
|
||||
return Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos);
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value, fs::WriteOption option) const {
|
||||
return Base::SetByPosition(pos, value, option);
|
||||
}
|
||||
};
|
||||
|
||||
struct RomEntryKey {
|
||||
Position parent;
|
||||
|
||||
bool IsEqual(const RomEntryKey &rhs, const void *aux_lhs, size_t aux_lhs_size, const void *aux_rhs, size_t aux_rhs_size) const {
|
||||
if (this->parent != rhs.parent) {
|
||||
return false;
|
||||
}
|
||||
if (aux_lhs_size != aux_rhs_size) {
|
||||
return false;
|
||||
}
|
||||
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
|
||||
}
|
||||
};
|
||||
static_assert(std::is_pod<RomEntryKey>::value);
|
||||
|
||||
struct EntryKey {
|
||||
RomEntryKey key;
|
||||
RomPathTool::RomEntryName name;
|
||||
|
||||
constexpr u32 Hash() const {
|
||||
u32 hash = this->key.parent ^ 123456789;
|
||||
const RomPathChar *name = this->name.path;
|
||||
const RomPathChar *end = name + this->name.length;
|
||||
while (name < end) {
|
||||
const u32 cur = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(name++)));
|
||||
hash = ((hash >> 5) | (hash << 27)) ^ cur;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_pod<EntryKey>::value);
|
||||
|
||||
using DirectoryEntryMapTable = EntryMapTable<DirectoryBucketStorage, DirectoryEntryStorage, RomEntryKey, EntryKey, RomDirectoryEntry>;
|
||||
using FileEntryMapTable = EntryMapTable<FileBucketStorage, FileEntryStorage, RomEntryKey, EntryKey, RomFileEntry>;
|
||||
private:
|
||||
DirectoryEntryMapTable dir_table;
|
||||
FileEntryMapTable file_table;
|
||||
public:
|
||||
static u32 QueryDirectoryEntrySize(u32 name_len) {
|
||||
AMS_ABORT_UNLESS(name_len <= RomPathTool::MaxPathLength);
|
||||
return DirectoryEntryMapTable::QueryEntrySize(name_len * sizeof(RomPathChar));
|
||||
}
|
||||
|
||||
static u32 QueryFileEntrySize(u32 name_len) {
|
||||
AMS_ABORT_UNLESS(name_len <= RomPathTool::MaxPathLength);
|
||||
return FileEntryMapTable::QueryEntrySize(name_len * sizeof(RomPathChar));
|
||||
}
|
||||
|
||||
static u32 QueryDirectoryEntryBucketStorageSize(u32 count) { return DirectoryEntryMapTable::QueryBucketStorageSize(count); }
|
||||
static u32 QueryFileEntryBucketStorageSize(u32 count) { return FileEntryMapTable::QueryBucketStorageSize(count); }
|
||||
|
||||
static Result Format(DirectoryBucketStorage *dir_bucket, s64 dir_bucket_ofs, u32 dir_bucket_size, DirectoryEntryStorage *dir_entry, s64 dir_entry_ofs, u32 dir_entry_size, FileBucketStorage *file_bucket, s64 file_bucket_ofs, u32 file_bucket_size, FileEntryStorage *file_entry, s64 file_entry_ofs, u32 file_entry_size) {
|
||||
R_TRY(DirectoryEntryMapTable::Format(dir_bucket, dir_bucket_ofs, DirectoryEntryMapTable::QueryBucketCount(dir_bucket_size), dir_entry, dir_entry_ofs, dir_entry_size));
|
||||
R_TRY(FileEntryMapTable::Format(file_bucket, file_bucket_ofs, FileEntryMapTable::QueryBucketCount(file_bucket_size), file_entry, file_entry_ofs, file_entry_size));
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
HierarchicalRomFileTable() { /* ... */ }
|
||||
|
||||
constexpr u32 GetDirectoryEntryCount() const {
|
||||
return this->dir_table.GetEntryCount();
|
||||
}
|
||||
|
||||
constexpr u32 GetFileEntryCount() const {
|
||||
return this->file_table.GetEntryCount();
|
||||
}
|
||||
|
||||
Result Initialize(DirectoryBucketStorage *dir_bucket, s64 dir_bucket_ofs, u32 dir_bucket_size, DirectoryEntryStorage *dir_entry, s64 dir_entry_ofs, u32 dir_entry_size, FileBucketStorage *file_bucket, s64 file_bucket_ofs, u32 file_bucket_size, FileEntryStorage *file_entry, s64 file_entry_ofs, u32 file_entry_size) {
|
||||
AMS_ASSERT(dir_bucket != nullptr);
|
||||
AMS_ASSERT(dir_entry != nullptr);
|
||||
AMS_ASSERT(file_bucket != nullptr);
|
||||
AMS_ASSERT(file_entry != nullptr);
|
||||
|
||||
R_TRY(this->dir_table.Initialize(dir_bucket, dir_bucket_ofs, DirectoryEntryMapTable::QueryBucketCount(dir_bucket_size), dir_entry, dir_entry_ofs, dir_entry_size));
|
||||
R_TRY(this->file_table.Initialize(file_bucket, file_bucket_ofs, FileEntryMapTable::QueryBucketCount(file_bucket_size), file_entry, file_entry_ofs, file_entry_size));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
this->dir_table.Finalize();
|
||||
this->file_table.Finalize();
|
||||
}
|
||||
|
||||
Result CreateRootDirectory() {
|
||||
Position root_pos = RootPosition;
|
||||
EntryKey root_key = {};
|
||||
root_key.key.parent = root_pos;
|
||||
RomPathTool::InitializeRomEntryName(std::addressof(root_key.name));
|
||||
RomDirectoryEntry root_entry = {
|
||||
.next = InvalidPosition,
|
||||
.dir = InvalidPosition,
|
||||
.file = InvalidPosition,
|
||||
};
|
||||
return this->dir_table.Add(std::addressof(root_pos), root_key, root_entry);
|
||||
}
|
||||
|
||||
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey new_key = {};
|
||||
R_TRY(this->FindDirectoryRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(new_key), path));
|
||||
|
||||
R_TRY(this->CheckSameEntryExists(new_key, fs::ResultDbmAlreadyExists()));
|
||||
|
||||
RomDirectoryEntry new_entry = {
|
||||
.next = InvalidPosition,
|
||||
.dir = InvalidPosition,
|
||||
.file = InvalidPosition,
|
||||
};
|
||||
|
||||
Position new_pos = 0;
|
||||
R_TRY_CATCH(this->dir_table.Add(std::addressof(new_pos), new_key, new_entry)) {
|
||||
R_CONVERT(fs::ResultDbmKeyFull, fs::ResultDbmDirectoryEntryFull())
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
*out = ConvertToDirectoryId(new_pos);
|
||||
|
||||
if (parent_entry.dir == InvalidPosition) {
|
||||
parent_entry.dir = new_pos;
|
||||
|
||||
R_TRY(this->dir_table.SetByPosition(new_key.key.parent, parent_entry, fs::WriteOption::None));
|
||||
} else {
|
||||
Position cur_pos = parent_entry.dir;
|
||||
while (true) {
|
||||
RomEntryKey cur_key = {};
|
||||
RomDirectoryEntry cur_entry = {};
|
||||
R_TRY(this->dir_table.GetByPosition(std::addressof(cur_key), std::addressof(cur_entry), nullptr, nullptr, cur_pos));
|
||||
|
||||
if (cur_entry.next == InvalidPosition) {
|
||||
cur_entry.next = new_pos;
|
||||
|
||||
R_TRY(this->dir_table.SetByPosition(cur_pos, cur_entry, fs::WriteOption::None));
|
||||
break;
|
||||
}
|
||||
|
||||
cur_pos = cur_entry.next;
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey new_key = {};
|
||||
R_TRY(this->FindFileRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(new_key), path));
|
||||
|
||||
R_TRY(this->CheckSameEntryExists(new_key, fs::ResultDbmAlreadyExists()));
|
||||
|
||||
RomFileEntry new_entry = {
|
||||
.next = InvalidPosition,
|
||||
.info = info,
|
||||
};
|
||||
|
||||
Position new_pos = 0;
|
||||
R_TRY_CATCH(this->file_table.Add(std::addressof(new_pos), new_key, new_entry)) {
|
||||
R_CONVERT(fs::ResultDbmKeyFull, fs::ResultDbmFileEntryFull())
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
*out = ConvertToFileId(new_pos);
|
||||
|
||||
if (parent_entry.file == InvalidPosition) {
|
||||
parent_entry.file = new_pos;
|
||||
|
||||
R_TRY(this->dir_table.SetByPosition(new_key.key.parent, parent_entry, fs::WriteOption::None));
|
||||
} else {
|
||||
Position cur_pos = parent_entry.file;
|
||||
while (true) {
|
||||
RomEntryKey cur_key = {};
|
||||
RomFileEntry cur_entry = {};
|
||||
R_TRY(this->file_table.GetByPosition(std::addressof(cur_key), std::addressof(cur_entry), nullptr, nullptr, cur_pos));
|
||||
|
||||
if (cur_entry.next == InvalidPosition) {
|
||||
cur_entry.next = new_pos;
|
||||
|
||||
R_TRY(this->file_table.SetByPosition(cur_pos, cur_entry, fs::WriteOption::None));
|
||||
break;
|
||||
}
|
||||
|
||||
cur_pos = cur_entry.next;
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey key = {};
|
||||
R_TRY(this->FindDirectoryRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(key), path));
|
||||
|
||||
Position pos = 0;
|
||||
RomDirectoryEntry entry = {};
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(pos), std::addressof(entry), key));
|
||||
|
||||
*out = ConvertToDirectoryId(pos);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ConvertPathToFileId(RomFileId *out, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey key = {};
|
||||
R_TRY(this->FindDirectoryRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(key), path));
|
||||
|
||||
Position pos = 0;
|
||||
RomFileEntry entry = {};
|
||||
R_TRY(this->GetFileEntry(std::addressof(pos), std::addressof(entry), key));
|
||||
|
||||
*out = ConvertToFileId(pos);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetDirectoryInformation(DirectoryInfo *out, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey key = {};
|
||||
R_TRY(this->FindDirectoryRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(key), path));
|
||||
|
||||
return this->GetDirectoryInformation(out, key);
|
||||
}
|
||||
|
||||
Result GetDirectoryInformation(DirectoryInfo *out, RomDirectoryId id) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
RomDirectoryEntry entry = {};
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(entry), id));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenFile(FileInfo *out, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey key = {};
|
||||
R_TRY(this->FindFileRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(key), path));
|
||||
|
||||
return this->OpenFile(out, key);
|
||||
}
|
||||
|
||||
Result OpenFile(FileInfo *out, RomFileId id) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
RomFileEntry entry = {};
|
||||
R_TRY(this->GetFileEntry(std::addressof(entry), id));
|
||||
|
||||
*out = entry.info;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindOpen(FindPosition *out, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
EntryKey parent_key = {};
|
||||
RomDirectoryEntry parent_entry = {};
|
||||
EntryKey key = {};
|
||||
R_TRY(this->FindDirectoryRecursive(std::addressof(parent_key), std::addressof(parent_entry), std::addressof(key), path));
|
||||
|
||||
return this->FindOpen(out, key);
|
||||
}
|
||||
|
||||
Result FindOpen(FindPosition *out, RomDirectoryId id) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
out->next_dir = InvalidPosition;
|
||||
out->next_file = InvalidPosition;
|
||||
|
||||
RomDirectoryEntry entry = {};
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(entry), id));
|
||||
|
||||
out->next_dir = entry.dir;
|
||||
out->next_file = entry.file;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindNextDirectory(RomPathChar *out, FindPosition *find) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(find != nullptr);
|
||||
|
||||
R_UNLESS(find->next_dir != InvalidPosition, fs::ResultDbmFindFinished());
|
||||
|
||||
RomEntryKey key = {};
|
||||
RomDirectoryEntry entry = {};
|
||||
size_t aux_size = 0;
|
||||
R_TRY(this->dir_table.GetByPosition(std::addressof(key), std::addressof(entry), out, std::addressof(aux_size), find->next_dir));
|
||||
|
||||
out[aux_size / sizeof(RomPathChar)] = RomStringTraits::NullTerminator;
|
||||
|
||||
find->next_dir = entry.next;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindNextFile(RomPathChar *out, FindPosition *find) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(find != nullptr);
|
||||
|
||||
R_UNLESS(find->next_file != InvalidPosition, fs::ResultDbmFindFinished());
|
||||
|
||||
RomEntryKey key = {};
|
||||
RomFileEntry entry = {};
|
||||
size_t aux_size = 0;
|
||||
R_TRY(this->file_table.GetByPosition(std::addressof(key), std::addressof(entry), out, std::addressof(aux_size), find->next_file));
|
||||
|
||||
out[aux_size / sizeof(RomPathChar)] = RomStringTraits::NullTerminator;
|
||||
|
||||
find->next_file = entry.next;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result QueryRomFileSystemSize(u32 *out_dir_entry_size, u32 *out_file_entry_size) {
|
||||
AMS_ASSERT(out_dir_entry_size != nullptr);
|
||||
AMS_ASSERT(out_file_entry_size != nullptr);
|
||||
|
||||
*out_dir_entry_size = this->dir_table.GetTotalEntrySize();
|
||||
*out_file_entry_size = this->file_table.GetTotalEntrySize();
|
||||
return ResultSuccess();
|
||||
}
|
||||
private:
|
||||
Result GetGrandParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_dir_key != nullptr);
|
||||
AMS_ASSERT(out_dir_entry != nullptr);
|
||||
|
||||
RomEntryKey gp_key = {};
|
||||
RomDirectoryEntry gp_entry = {};
|
||||
R_TRY(this->dir_table.GetByPosition(std::addressof(gp_key), std::addressof(gp_entry), nullptr, nullptr, pos));
|
||||
out_dir_key->key.parent = gp_key.parent;
|
||||
|
||||
R_TRY(RomPathTool::GetParentDirectoryName(std::addressof(out_dir_key->name), name, path));
|
||||
|
||||
R_TRY(this->GetDirectoryEntry(out_pos, out_dir_entry, *out_dir_key));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser &parser, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_dir_key != nullptr);
|
||||
AMS_ASSERT(out_dir_entry != nullptr);
|
||||
|
||||
Position dir_pos = RootPosition;
|
||||
EntryKey dir_key = {};
|
||||
RomDirectoryEntry dir_entry = {};
|
||||
dir_key.key.parent = RootPosition;
|
||||
|
||||
R_TRY(parser.GetNextDirectoryName(std::addressof(dir_key.name)));
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(dir_pos), std::addressof(dir_entry), dir_key));
|
||||
|
||||
Position parent_pos = dir_pos;
|
||||
while (!parser.IsFinished()) {
|
||||
EntryKey old_key = dir_key;
|
||||
|
||||
R_TRY(parser.GetNextDirectoryName(std::addressof(dir_key.name)));
|
||||
|
||||
if (RomPathTool::IsCurrentDirectory(dir_key.name)) {
|
||||
dir_key = old_key;
|
||||
continue;
|
||||
} else if (RomPathTool::IsParentDirectory(dir_key.name)) {
|
||||
R_UNLESS(parent_pos != RootPosition, fs::ResultDbmInvalidOperation());
|
||||
|
||||
R_TRY(this->GetGrandParent(std::addressof(parent_pos), std::addressof(dir_key), std::addressof(dir_entry), dir_key.key.parent, dir_key.name, path));
|
||||
} else {
|
||||
dir_key.key.parent = parent_pos;
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(dir_pos), std::addressof(dir_entry), dir_key));
|
||||
|
||||
parent_pos = dir_pos;
|
||||
}
|
||||
}
|
||||
|
||||
*out_pos = parent_pos;
|
||||
*out_dir_key = dir_key;
|
||||
*out_dir_entry = dir_entry;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindPathRecursive(EntryKey *out_parent_key, RomDirectoryEntry *out_parent_dir_entry, EntryKey *out_key, bool is_dir, const RomPathChar *path) const {
|
||||
AMS_ASSERT(out_parent_key != nullptr);
|
||||
AMS_ASSERT(out_parent_dir_entry != nullptr);
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(path != nullptr);
|
||||
|
||||
RomPathTool::PathParser parser;
|
||||
R_TRY(parser.Initialize(path));
|
||||
|
||||
Position parent_pos = 0;
|
||||
R_TRY(this->FindParentDirectoryRecursive(std::addressof(parent_pos), out_parent_key, out_parent_dir_entry, parser, path));
|
||||
|
||||
if (is_dir) {
|
||||
RomPathTool::RomEntryName name = {};
|
||||
R_TRY(parser.GetAsDirectoryName(std::addressof(name)));
|
||||
|
||||
if (RomPathTool::IsCurrentDirectory(name)) {
|
||||
*out_key = *out_parent_key;
|
||||
if (out_key->key.parent != RootPosition) {
|
||||
Position pos = 0;
|
||||
R_TRY(this->GetGrandParent(std::addressof(pos), out_parent_key, out_parent_dir_entry, out_key->key.parent, out_key->name, path));
|
||||
}
|
||||
} else if (RomPathTool::IsParentDirectory(name)) {
|
||||
R_UNLESS(parent_pos != RootPosition, fs::ResultDbmInvalidOperation());
|
||||
|
||||
Position pos = 0;
|
||||
RomDirectoryEntry cur_entry = {};
|
||||
R_TRY(this->GetGrandParent(std::addressof(pos), out_key, std::addressof(cur_entry), out_parent_key->key.parent, out_parent_key->name, path));
|
||||
|
||||
if (out_key->key.parent != RootPosition) {
|
||||
R_TRY(this->GetGrandParent(std::addressof(pos), out_parent_key, out_parent_dir_entry, out_key->key.parent, out_key->name, path));
|
||||
}
|
||||
} else {
|
||||
out_key->name = name;
|
||||
out_key->key.parent = (out_key->name.length > 0) ? parent_pos : RootPosition;
|
||||
}
|
||||
} else {
|
||||
R_UNLESS(!parser.IsDirectoryPath(), fs::ResultDbmInvalidOperation());
|
||||
|
||||
out_key->key.parent = parent_pos;
|
||||
R_TRY(parser.GetAsFileName(std::addressof(out_key->name)));
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindDirectoryRecursive(EntryKey *out_parent_key, RomDirectoryEntry *out_parent_dir_entry, EntryKey *out_key, const RomPathChar *path) const {
|
||||
return this->FindPathRecursive(out_parent_key, out_parent_dir_entry, out_key, true, path);
|
||||
}
|
||||
|
||||
Result FindFileRecursive(EntryKey *out_parent_key, RomDirectoryEntry *out_parent_dir_entry, EntryKey *out_key, const RomPathChar *path) const {
|
||||
return this->FindPathRecursive(out_parent_key, out_parent_dir_entry, out_key, false, path);
|
||||
}
|
||||
|
||||
Result CheckSameEntryExists(const EntryKey &key, Result if_exists) const {
|
||||
/* Check dir */
|
||||
{
|
||||
Position pos = InvalidPosition;
|
||||
RomDirectoryEntry entry = {};
|
||||
const Result get_res = this->dir_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
||||
R_TRY(get_res);
|
||||
return if_exists;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check file */
|
||||
{
|
||||
Position pos = InvalidPosition;
|
||||
RomFileEntry entry = {};
|
||||
const Result get_res = this->file_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
||||
R_TRY(get_res);
|
||||
return if_exists;
|
||||
}
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetDirectoryEntry(Position *out_pos, RomDirectoryEntry *out_entry, const EntryKey &key) const {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_entry != nullptr);
|
||||
|
||||
const Result dir_res = this->dir_table.Get(out_pos, out_entry, key);
|
||||
R_UNLESS(R_FAILED(dir_res), dir_res);
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(dir_res), dir_res);
|
||||
|
||||
Position pos = 0;
|
||||
RomFileEntry entry = {};
|
||||
const Result file_res = this->file_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||
R_UNLESS(R_FAILED(file_res), fs::ResultDbmInvalidOperation());
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(file_res), fs::ResultDbmDirectoryNotFound());
|
||||
return file_res;
|
||||
}
|
||||
|
||||
Result GetDirectoryEntry(RomDirectoryEntry *out_entry, RomDirectoryId id) const {
|
||||
AMS_ASSERT(out_entry != nullptr);
|
||||
Position pos = ConvertToPosition(id);
|
||||
|
||||
RomEntryKey key = {};
|
||||
const Result dir_res = this->dir_table.GetByPosition(std::addressof(key), out_entry, nullptr, nullptr, pos);
|
||||
R_UNLESS(R_FAILED(dir_res), dir_res);
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(dir_res), dir_res);
|
||||
|
||||
RomFileEntry entry = {};
|
||||
const Result file_res = this->file_table.GetByPosition(std::addressof(key), std::addressof(entry), nullptr, nullptr, pos);
|
||||
R_UNLESS(R_FAILED(file_res), fs::ResultDbmInvalidOperation());
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(file_res), fs::ResultDbmDirectoryNotFound());
|
||||
return file_res;
|
||||
}
|
||||
|
||||
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key) const {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_entry != nullptr);
|
||||
|
||||
const Result file_res = this->file_table.Get(out_pos, out_entry, key);
|
||||
R_UNLESS(R_FAILED(file_res), file_res);
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(file_res), file_res);
|
||||
|
||||
Position pos = 0;
|
||||
RomDirectoryEntry entry = {};
|
||||
const Result dir_res = this->dir_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||
R_UNLESS(R_FAILED(dir_res), fs::ResultDbmInvalidOperation());
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(dir_res), fs::ResultDbmFileNotFound());
|
||||
return dir_res;
|
||||
}
|
||||
|
||||
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id) const {
|
||||
AMS_ASSERT(out_entry != nullptr);
|
||||
Position pos = ConvertToPosition(id);
|
||||
|
||||
RomEntryKey key = {};
|
||||
const Result file_res = this->file_table.GetByPosition(std::addressof(key), out_entry, nullptr, nullptr, pos);
|
||||
R_UNLESS(R_FAILED(file_res), file_res);
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(file_res), file_res);
|
||||
|
||||
RomDirectoryEntry entry = {};
|
||||
const Result dir_res = this->dir_table.GetByPosition(std::addressof(key), std::addressof(entry), nullptr, nullptr, pos);
|
||||
R_UNLESS(R_FAILED(dir_res), fs::ResultDbmInvalidOperation());
|
||||
R_UNLESS(!fs::ResultDbmKeyNotFound::Includes(dir_res), fs::ResultDbmFileNotFound());
|
||||
return dir_res;
|
||||
}
|
||||
|
||||
Result GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
Position pos = 0;
|
||||
RomDirectoryEntry entry = {};
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(pos), std::addressof(entry), key));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenFile(FileInfo *out, const EntryKey &key) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
Position pos = 0;
|
||||
RomFileEntry entry = {};
|
||||
R_TRY(this->GetFileEntry(std::addressof(pos), std::addressof(entry), key));
|
||||
|
||||
*out = entry.info;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindOpen(FindPosition *out, const EntryKey &key) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
out->next_dir = InvalidPosition;
|
||||
out->next_file = InvalidPosition;
|
||||
|
||||
Position pos = 0;
|
||||
RomDirectoryEntry entry = {};
|
||||
R_TRY(this->GetDirectoryEntry(std::addressof(pos), std::addressof(entry), key));
|
||||
|
||||
out->next_dir = entry.dir;
|
||||
out->next_file = entry.file;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,367 +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/fssystem/fssystem_dbm_rom_types.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
constexpr ALWAYS_INLINE u32 AlignRomAddress(u32 addr) {
|
||||
return util::AlignUp(addr, sizeof(addr));
|
||||
}
|
||||
|
||||
template<typename BucketStorageType, typename EntryStorageType, typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||
class RomKeyValueStorage {
|
||||
public:
|
||||
using BucketStorage = BucketStorageType;
|
||||
using EntryStorage = EntryStorageType;
|
||||
using Key = KeyType;
|
||||
using Value = ValueType;
|
||||
using Position = u32;
|
||||
using BucketIndex = u32;
|
||||
|
||||
struct FindIndex {
|
||||
BucketIndex ind;
|
||||
Position pos;
|
||||
};
|
||||
static_assert(std::is_pod<FindIndex>::value);
|
||||
private:
|
||||
static constexpr inline Position InvalidPosition = ~Position();
|
||||
|
||||
struct Element {
|
||||
Key key;
|
||||
Value value;
|
||||
Position next;
|
||||
u32 size;
|
||||
};
|
||||
static_assert(std::is_pod<Element>::value);
|
||||
private:
|
||||
s64 bucket_offset;
|
||||
u32 bucket_count;
|
||||
BucketStorage *bucket_storage;
|
||||
s64 kv_offset;
|
||||
u32 kv_size;
|
||||
EntryStorage *kv_storage;
|
||||
u32 total_entry_size;
|
||||
u32 entry_count;
|
||||
public:
|
||||
static constexpr u32 QueryEntrySize(u32 aux_size) {
|
||||
return AlignRomAddress(sizeof(Element) + aux_size);
|
||||
}
|
||||
|
||||
static constexpr u32 QueryBucketStorageSize(u32 num) {
|
||||
return num * sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr u32 QueryBucketCount(u32 size) {
|
||||
return size / sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr u32 QueryKeyValueStorageSize(u32 num) {
|
||||
return num * sizeof(Element);
|
||||
}
|
||||
|
||||
static Result Format(BucketStorage *bucket, s64 bucket_ofs, u32 bucket_count, EntryStorage *kv, s64 kv_ofs, u32 kv_size) {
|
||||
AMS_ASSERT(bucket != nullptr);
|
||||
AMS_ASSERT(kv != nullptr);
|
||||
AMS_ASSERT(kv_size >= 0);
|
||||
|
||||
const Position pos = InvalidPosition;
|
||||
for (s64 i = 0; i < bucket_count; i++) {
|
||||
R_TRY(bucket->Write(bucket_ofs + i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
RomKeyValueStorage() : bucket_offset(), bucket_count(), bucket_storage(), kv_offset(), kv_size(), kv_storage(), total_entry_size(), entry_count() { /* ... */ }
|
||||
|
||||
Result Initialize(BucketStorage *bucket, s64 bucket_ofs, u32 bucket_count, EntryStorage *kv, s64 kv_ofs, u32 kv_size) {
|
||||
AMS_ASSERT(bucket != nullptr);
|
||||
AMS_ASSERT(kv != nullptr);
|
||||
AMS_ASSERT(bucket_count > 0);
|
||||
|
||||
this->bucket_storage = bucket;
|
||||
this->bucket_offset = bucket_ofs;
|
||||
this->bucket_count = bucket_count;
|
||||
|
||||
this->kv_storage = kv;
|
||||
this->kv_offset = kv_ofs;
|
||||
this->kv_size = kv_size;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
this->bucket_storage = nullptr;
|
||||
this->bucket_offset = 0;
|
||||
this->bucket_count = 0;
|
||||
|
||||
this->kv_storage = nullptr;
|
||||
this->kv_offset = 0;
|
||||
this->kv_size = 0;
|
||||
}
|
||||
|
||||
constexpr u32 GetTotalEntrySize() const {
|
||||
return this->total_entry_size;
|
||||
}
|
||||
|
||||
constexpr u32 GetFreeSize() const {
|
||||
return (this->kv_size - this->total_entry_size);
|
||||
}
|
||||
|
||||
constexpr u32 GetEntryCount() const {
|
||||
return this->entry_count;
|
||||
}
|
||||
|
||||
Result Add(const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
AMS_ASSERT(aux_size <= MaxAuxiliarySize);
|
||||
Position pos;
|
||||
return this->AddImpl(std::addressof(pos), key, hash_key, aux, aux_size, value);
|
||||
}
|
||||
|
||||
Result Get(Value *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
AMS_ASSERT(aux_size <= MaxAuxiliarySize);
|
||||
Position pos;
|
||||
return this->GetImpl(std::addressof(pos), out, key, hash_key, aux, aux_size);
|
||||
}
|
||||
|
||||
void FindOpen(FindIndex *out) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
out->ind = static_cast<BucketIndex>(-1);
|
||||
out->pos = InvalidPosition;
|
||||
}
|
||||
|
||||
Result FindNext(Key *out_key, Value *out_val, FindIndex *find) {
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
AMS_ASSERT(find != nullptr);
|
||||
|
||||
Element elem;
|
||||
|
||||
BucketIndex ind = find->ind;
|
||||
R_UNLESS((ind < this->bucket_count) || ind == static_cast<BucketIndex>(-1), fs::ResultDbmFindKeyFinished());
|
||||
|
||||
while (true) {
|
||||
if (find->pos != InvalidPosition) {
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), nullptr, nullptr, find->pos));
|
||||
|
||||
AMS_ASSERT(elem.next == InvalidPosition || elem.next < this->kv_size);
|
||||
find->pos = elem.next;
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.val;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
ind++;
|
||||
if (ind == this->bucket_count) {
|
||||
find->ind = ind;
|
||||
find->pos = InvalidPosition;
|
||||
return fs::ResultDbmFindKeyFinished();
|
||||
}
|
||||
|
||||
Position pos;
|
||||
R_TRY(this->ReadBucket(std::addressof(pos), ind));
|
||||
AMS_ASSERT(pos == InvalidPosition || pos < this->kv_size);
|
||||
|
||||
if (pos != InvalidPosition) {
|
||||
find->ind = ind;
|
||||
find->pos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected:
|
||||
Result AddImpl(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(this->bucket_count > 0);
|
||||
AMS_ASSERT(this->kv_size >= 0);
|
||||
|
||||
const Result find_res = this->FindImpl(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size);
|
||||
R_UNLESS(R_FAILED(find_res), fs::ResultDbmAlreadyExists());
|
||||
R_UNLESS(fs::ResultDbmKeyNotFound::Includes(find_res), find_res);
|
||||
|
||||
R_TRY(this->AllocateEntry(std::addressof(pos), aux_size));
|
||||
|
||||
Position next_pos;
|
||||
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
||||
|
||||
elem = { key, value, next_pos, static_cast<u32>(aux_size) };
|
||||
*out = pos;
|
||||
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size, fs::WriteOption::None));
|
||||
|
||||
this->entry_count++;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetImpl(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) const {
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
|
||||
R_TRY(this->FindImpl(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size));
|
||||
|
||||
*out_pos = pos;
|
||||
*out_val = elem.value;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) const {
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), out_aux, out_aux_size, pos));
|
||||
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.value;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value, fs::WriteOption option) const {
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), nullptr, nullptr, pos));
|
||||
elem.value = value;
|
||||
return this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0, option);
|
||||
}
|
||||
private:
|
||||
BucketIndex HashToBucket(u32 hash_key) const {
|
||||
return hash_key % this->bucket_count;
|
||||
}
|
||||
|
||||
Result FindImpl(Position *out_pos, Position *out_prev, Element *out_elem, const Key &key, u32 hash_key, const void *aux, size_t aux_size) const {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_prev != nullptr);
|
||||
AMS_ASSERT(out_elem != nullptr);
|
||||
AMS_ASSERT(this->bucket_count > 0);
|
||||
AMS_ASSERT(this->kv_size >= 0);
|
||||
|
||||
*out_pos = 0;
|
||||
*out_prev = 0;
|
||||
|
||||
const BucketIndex ind = HashToBucket(hash_key);
|
||||
|
||||
Position cur;
|
||||
R_TRY(this->ReadBucket(std::addressof(cur), ind));
|
||||
AMS_ASSERT(cur == InvalidPosition || cur < this->kv_size);
|
||||
|
||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||
|
||||
u8 buf[MaxAuxiliarySize];
|
||||
|
||||
while (true) {
|
||||
size_t cur_aux_size;
|
||||
R_TRY(this->ReadKeyValue(out_elem, buf, std::addressof(cur_aux_size), cur));
|
||||
|
||||
if (key.IsEqual(out_elem->key, aux, aux_size, buf, cur_aux_size)) {
|
||||
*out_pos = cur;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
*out_prev = cur;
|
||||
cur = out_elem->next;
|
||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||
}
|
||||
}
|
||||
|
||||
Result AllocateEntry(Position *out, size_t aux_size) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
R_UNLESS(this->total_entry_size + sizeof(Element) + aux_size <= this->kv_size, fs::ResultDbmKeyFull());
|
||||
|
||||
*out = static_cast<Position>(this->total_entry_size);
|
||||
|
||||
this->total_entry_size = AlignRomAddress(this->total_entry_size + sizeof(Element) + static_cast<u32>(aux_size));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
const BucketIndex ind = HashToBucket(hash_key);
|
||||
|
||||
Position next;
|
||||
R_TRY(this->ReadBucket(std::addressof(next), ind));
|
||||
AMS_ASSERT(next == InvalidPosition || next < this->kv_size);
|
||||
|
||||
R_TRY(this->WriteBucket(pos, ind, fs::WriteOption::None));
|
||||
|
||||
*out = next;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadBucket(Position *out, BucketIndex ind) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(this->bucket_storage != nullptr);
|
||||
AMS_ASSERT(ind < this->bucket_count);
|
||||
|
||||
const s64 offset = this->bucket_offset + ind * sizeof(Position);
|
||||
return this->bucket_storage->Read(offset, out, sizeof(*out));
|
||||
}
|
||||
|
||||
Result WriteBucket(Position pos, BucketIndex ind, fs::WriteOption option) const {
|
||||
AMS_ASSERT(this->bucket_storage != nullptr);
|
||||
AMS_ASSERT(ind < this->bucket_count);
|
||||
|
||||
const s64 offset = this->bucket_offset + ind * sizeof(Position);
|
||||
return this->bucket_storage.Write(offset, std::addressof(pos), sizeof(pos));
|
||||
}
|
||||
|
||||
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(this->kv_storage != nullptr);
|
||||
AMS_ASSERT(pos < this->kv_size);
|
||||
|
||||
const s64 offset = this->kv_offset + pos;
|
||||
R_TRY(this->kv_storage->Read(offset, out, sizeof(*out)));
|
||||
|
||||
if (out_aux != nullptr && out_aux_size != nullptr) {
|
||||
*out_aux_size = out->size;
|
||||
if (out->size > 0) {
|
||||
R_TRY(this->kv_storage->Read(offset + sizeof(*out), out_aux, out->size));
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size, fs::WriteOption option) const {
|
||||
AMS_ASSERT(elem != nullptr);
|
||||
AMS_ASSERT(this->kv_storage != nullptr);
|
||||
AMS_ASSERT(pos < this->kv_size);
|
||||
|
||||
const s64 offset = this->kv_offset + pos;
|
||||
R_TRY(this->kv_storage->Write(offset, elem, sizeof(*elem)));
|
||||
|
||||
if (aux != nullptr && aux_size > 0) {
|
||||
R_TRY(this->kv_storage->Write(offset + sizeof(*elem), aux, aux_size));
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,114 +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/fssystem/fssystem_dbm_rom_types.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
namespace RomPathTool {
|
||||
|
||||
constexpr inline u32 MaxPathLength = 0x300;
|
||||
|
||||
struct RomEntryName {
|
||||
size_t length;
|
||||
const RomPathChar *path;
|
||||
};
|
||||
static_assert(std::is_pod<RomEntryName>::value);
|
||||
|
||||
constexpr void InitializeRomEntryName(RomEntryName *entry) {
|
||||
entry->length = 0;
|
||||
}
|
||||
|
||||
constexpr inline bool IsSeparator(RomPathChar c) {
|
||||
return c == RomStringTraits::DirectorySeparator;
|
||||
}
|
||||
|
||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
||||
return c == RomStringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
constexpr inline bool IsDot(RomPathChar c) {
|
||||
return c == RomStringTraits::Dot;
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
|
||||
return name.length == 1 && IsDot(name.path[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||
return length == 1 && IsDot(p[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p) {
|
||||
return IsDot(p[0]) && IsNullTerminator(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomEntryName &name) {
|
||||
return name.length == 2 && IsDot(name.path[0]) && IsDot(name.path[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p) {
|
||||
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p, size_t length) {
|
||||
return length == 2 && IsDot(p[0]) && IsDot(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualPath(const RomPathChar *lhs, const RomPathChar *rhs, size_t length) {
|
||||
return std::strncmp(lhs, rhs, length) == 0;
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualName(const RomEntryName &lhs, const RomPathChar *rhs) {
|
||||
if (strnlen(rhs, MaxPathLength) != lhs.length) {
|
||||
return false;
|
||||
}
|
||||
return IsEqualPath(lhs.path, rhs, lhs.length);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualName(const RomEntryName &lhs, const RomEntryName &rhs) {
|
||||
if (lhs.length != rhs.length) {
|
||||
return false;
|
||||
}
|
||||
return IsEqualPath(lhs.path, rhs.path, lhs.length);
|
||||
}
|
||||
|
||||
Result GetParentDirectoryName(RomEntryName *out, const RomEntryName &cur, const RomPathChar *p);
|
||||
|
||||
class PathParser {
|
||||
private:
|
||||
const RomPathChar *prev_path_start;
|
||||
const RomPathChar *prev_path_end;
|
||||
const RomPathChar *next_path;
|
||||
bool finished;
|
||||
public:
|
||||
constexpr PathParser() : prev_path_start(), prev_path_end(), next_path(), finished() { /* ... */ }
|
||||
|
||||
Result Initialize(const RomPathChar *path);
|
||||
void Finalize();
|
||||
|
||||
bool IsFinished() const;
|
||||
bool IsDirectoryPath() const;
|
||||
|
||||
Result GetAsDirectoryName(RomEntryName *out) const;
|
||||
Result GetAsFileName(RomEntryName *out) const;
|
||||
|
||||
Result GetNextDirectoryName(RomEntryName *out);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +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/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
using RomPathChar = char;
|
||||
using RomFileId = s32;
|
||||
using RomDirectoryId = s32;
|
||||
|
||||
struct RomFileSystemInformation {
|
||||
s64 size;
|
||||
s64 directory_bucket_offset;
|
||||
s64 directory_bucket_size;
|
||||
s64 directory_entry_offset;
|
||||
s64 directory_entry_size;
|
||||
s64 file_bucket_offset;
|
||||
s64 file_bucket_size;
|
||||
s64 file_entry_offset;
|
||||
s64 file_entry_size;
|
||||
s64 body_offset;
|
||||
};
|
||||
static_assert(std::is_pod<RomFileSystemInformation>::value);
|
||||
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
||||
|
||||
struct RomDirectoryInfo {
|
||||
/* ... */
|
||||
};
|
||||
static_assert(std::is_pod<RomDirectoryInfo>::value);
|
||||
|
||||
struct RomFileInfo {
|
||||
fs::Int64 offset;
|
||||
fs::Int64 size;
|
||||
};
|
||||
static_assert(std::is_pod<RomFileInfo>::value);
|
||||
|
||||
namespace RomStringTraits {
|
||||
|
||||
constexpr inline char DirectorySeparator = '/';
|
||||
constexpr inline char NullTerminator = '\x00';
|
||||
constexpr inline char Dot = '.';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +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/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
constexpr inline size_t BufferPoolAlignment = 4_KB;
|
||||
constexpr inline size_t BufferPoolWorkSize = 320;
|
||||
|
||||
class PooledBuffer {
|
||||
NON_COPYABLE(PooledBuffer);
|
||||
private:
|
||||
char *buffer;
|
||||
size_t size;
|
||||
private:
|
||||
static size_t GetAllocatableSizeMaxCore(bool large);
|
||||
public:
|
||||
static size_t GetAllocatableSizeMax() { return GetAllocatableSizeMaxCore(false); }
|
||||
static size_t GetAllocatableParticularlyLargeSizeMax() { return GetAllocatableSizeMaxCore(true); }
|
||||
private:
|
||||
void Swap(PooledBuffer &rhs) {
|
||||
std::swap(this->buffer, rhs.buffer);
|
||||
std::swap(this->size, rhs.size);
|
||||
}
|
||||
public:
|
||||
/* Constructor/Destructor. */
|
||||
constexpr PooledBuffer() : buffer(), size() { /* ... */ }
|
||||
|
||||
PooledBuffer(size_t ideal_size, size_t required_size) : buffer(), size() {
|
||||
this->Allocate(ideal_size, required_size);
|
||||
}
|
||||
|
||||
~PooledBuffer() {
|
||||
this->Deallocate();
|
||||
}
|
||||
|
||||
/* Move and assignment. */
|
||||
explicit PooledBuffer(PooledBuffer &&rhs) : buffer(rhs.buffer), size(rhs.size) {
|
||||
rhs.buffer = nullptr;
|
||||
rhs.size = 0;
|
||||
}
|
||||
|
||||
PooledBuffer &operator=(PooledBuffer &&rhs) {
|
||||
PooledBuffer(std::move(rhs)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Allocation API. */
|
||||
void Allocate(size_t ideal_size, size_t required_size) {
|
||||
return this->AllocateCore(ideal_size, required_size, false);
|
||||
}
|
||||
|
||||
void AllocateParticularlyLarge(size_t ideal_size, size_t required_size) {
|
||||
return this->AllocateCore(ideal_size, required_size, true);
|
||||
}
|
||||
|
||||
void Shrink(size_t ideal_size);
|
||||
|
||||
void Deallocate() {
|
||||
/* Shrink the buffer to empty. */
|
||||
this->Shrink(0);
|
||||
AMS_ASSERT(this->buffer == nullptr);
|
||||
}
|
||||
|
||||
char *GetBuffer() const {
|
||||
AMS_ASSERT(this->buffer != nullptr);
|
||||
return this->buffer;
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
AMS_ASSERT(this->buffer != nullptr);
|
||||
return this->size;
|
||||
}
|
||||
private:
|
||||
void AllocateCore(size_t ideal_size, size_t required_size, bool large);
|
||||
};
|
||||
|
||||
Result InitializeBufferPool(char *buffer, size_t size);
|
||||
Result InitializeBufferPool(char *buffer, size_t size, char *work, size_t work_size);
|
||||
|
||||
bool IsPooledBuffer(const void *buffer);
|
||||
|
||||
size_t GetPooledBufferRetriedCount();
|
||||
size_t GetPooledBufferReduceAllocationCount();
|
||||
size_t GetPooledBufferFreeSizePeak();
|
||||
|
||||
void ClearPooledBufferPeak();
|
||||
|
||||
void RegisterAdditionalDeviceAddress(uintptr_t address, size_t size);
|
||||
void UnregisterAdditionalDeviceAddress(uintptr_t address);
|
||||
bool IsAdditionalDeviceAddress(const void *ptr);
|
||||
|
||||
inline bool IsDeviceAddress(const void *buffer) {
|
||||
return IsPooledBuffer(buffer) || IsAdditionalDeviceAddress(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +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/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_dbm_hierarchical_rom_file_table.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class RomFsFileSystem : public fs::fsa::IFileSystem, public fs::impl::Newable {
|
||||
NON_COPYABLE(RomFsFileSystem);
|
||||
public:
|
||||
using RomFileTable = HierarchicalRomFileTable<fs::IStorage, fs::IStorage, fs::IStorage, fs::IStorage>;
|
||||
private:
|
||||
RomFileTable rom_file_table;
|
||||
fs::IStorage *base_storage;
|
||||
std::shared_ptr<fs::IStorage> shared_storage;
|
||||
std::unique_ptr<fs::IStorage> dir_bucket_storage;
|
||||
std::unique_ptr<fs::IStorage> dir_entry_storage;
|
||||
std::unique_ptr<fs::IStorage> file_bucket_storage;
|
||||
std::unique_ptr<fs::IStorage> file_entry_storage;
|
||||
s64 entry_size;
|
||||
private:
|
||||
Result GetFileInfo(RomFileTable::FileInfo *out, const char *path);
|
||||
public:
|
||||
static Result GetRequiredWorkingMemorySize(size_t *out, fs::IStorage *storage);
|
||||
public:
|
||||
RomFsFileSystem();
|
||||
virtual ~RomFsFileSystem() override;
|
||||
|
||||
Result Initialize(fs::IStorage *base, void *work, size_t work_size, bool use_cache);
|
||||
Result Initialize(std::shared_ptr<fs::IStorage> base, void *work, size_t work_size, bool use_cache);
|
||||
|
||||
fs::IStorage *GetBaseStorage();
|
||||
RomFileTable *GetRomFileTable();
|
||||
Result GetFileBaseOffset(s64 *out, const char *path);
|
||||
public:
|
||||
virtual Result CreateFileImpl(const char *path, s64 size, int flags) override;
|
||||
virtual Result DeleteFileImpl(const char *path) override;
|
||||
virtual Result CreateDirectoryImpl(const char *path) override;
|
||||
virtual Result DeleteDirectoryImpl(const char *path) override;
|
||||
virtual Result DeleteDirectoryRecursivelyImpl(const char *path) override;
|
||||
virtual Result RenameFileImpl(const char *old_path, const char *new_path) override;
|
||||
virtual Result RenameDirectoryImpl(const char *old_path, const char *new_path) override;
|
||||
virtual Result GetEntryTypeImpl(fs::DirectoryEntryType *out, const char *path) override;
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fs::fsa::IFile> *out_file, const char *path, fs::OpenMode mode) override;
|
||||
virtual Result OpenDirectoryImpl(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const char *path, fs::OpenDirectoryMode mode) override;
|
||||
virtual Result CommitImpl() override;
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) override;
|
||||
virtual Result CleanDirectoryRecursivelyImpl(const char *path) override;
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
virtual Result CommitProvisionallyImpl(s64 counter) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,39 +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>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class ScopedThreadPriorityChanger {
|
||||
public:
|
||||
enum class Mode {
|
||||
Absolute,
|
||||
Relative,
|
||||
};
|
||||
private:
|
||||
/* TODO */
|
||||
public:
|
||||
ALWAYS_INLINE explicit ScopedThreadPriorityChanger(s32 priority, Mode mode) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~ScopedThreadPriorityChanger() {
|
||||
/* TODO */
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -170,6 +170,4 @@ namespace ams::fssystem {
|
||||
}
|
||||
}
|
||||
|
||||
void AddCounter(void *counter, size_t counter_size, u64 value);
|
||||
|
||||
}
|
||||
|
||||
@@ -14,16 +14,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include "../../fs/fs_common.hpp"
|
||||
#include "../../fs/fsa/fs_ifile.hpp"
|
||||
#include "../../fs/fsa/fs_idirectory.hpp"
|
||||
#include "../../fs/fsa/fs_ifilesystem.hpp"
|
||||
|
||||
namespace ams::fssystem::impl {
|
||||
|
||||
template<typename Impl>
|
||||
class IPathResolutionFileSystem : public fs::fsa::IFileSystem, public fs::impl::Newable {
|
||||
class IPathResolutionFileSystem : public fs::fsa::IFileSystem {
|
||||
NON_COPYABLE(IPathResolutionFileSystem);
|
||||
private:
|
||||
std::shared_ptr<fs::fsa::IFileSystem> shared_fs;
|
||||
|
||||
@@ -20,20 +20,19 @@
|
||||
namespace ams::hos {
|
||||
|
||||
enum Version : u16 {
|
||||
Version_Min = 0,
|
||||
Version_1_0_0 = Version_Min,
|
||||
Version_2_0_0 = 1,
|
||||
Version_3_0_0 = 2,
|
||||
Version_4_0_0 = 3,
|
||||
Version_5_0_0 = 4,
|
||||
Version_6_0_0 = 5,
|
||||
Version_7_0_0 = 6,
|
||||
Version_8_0_0 = 7,
|
||||
Version_8_1_0 = 8,
|
||||
Version_9_0_0 = 9,
|
||||
Version_9_1_0 = 10,
|
||||
Version_10_0_0 = 11,
|
||||
Version_Current = Version_10_0_0,
|
||||
Version_Min = 0,
|
||||
Version_100 = Version_Min,
|
||||
Version_200 = 1,
|
||||
Version_300 = 2,
|
||||
Version_400 = 3,
|
||||
Version_500 = 4,
|
||||
Version_600 = 5,
|
||||
Version_700 = 6,
|
||||
Version_800 = 7,
|
||||
Version_810 = 8,
|
||||
Version_900 = 9,
|
||||
Version_910 = 10,
|
||||
Version_Current = Version_910,
|
||||
Version_Max = 32,
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace ams::kvdb {
|
||||
rhs.size = 0;
|
||||
}
|
||||
|
||||
AutoBuffer &operator=(AutoBuffer &&rhs) {
|
||||
AutoBuffer& operator=(AutoBuffer &&rhs) {
|
||||
AutoBuffer(std::move(rhs)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace ams::kvdb {
|
||||
Path GetPath(const void *key, size_t key_size);
|
||||
Result GetKey(size_t *out_size, void *out_key, size_t max_out_size, const FileName &file_name);
|
||||
public:
|
||||
FileKeyValueStore() : lock(false) { /* ... */ }
|
||||
FileKeyValueStore() { /* ... */ }
|
||||
|
||||
/* Basic accessors. */
|
||||
Result Initialize(const char *dir);
|
||||
|
||||
@@ -16,6 +16,5 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stratosphere/ldr/ldr_types.hpp>
|
||||
#include <stratosphere/ldr/ldr_shell_api.hpp>
|
||||
#include <stratosphere/ldr/ldr_pm_api.hpp>
|
||||
#include "ldr/ldr_types.hpp"
|
||||
#include "ldr/ldr_pm_api.hpp"
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace ams::ldr::pm {
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc);
|
||||
Result UnpinProgram(PinId pin_id);
|
||||
Result SetEnabledProgramVerification(bool enabled);
|
||||
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id);
|
||||
|
||||
/* Atmosphere extension API. */
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -221,8 +221,7 @@ namespace ams::ldr {
|
||||
};
|
||||
|
||||
u32 magic;
|
||||
u32 signature_key_generation;
|
||||
u8 reserved_08[4];
|
||||
u8 reserved_04[8];
|
||||
u8 flags;
|
||||
u8 reserved_0D;
|
||||
u8 main_thread_priority;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user