diff --git a/README.md b/README.md index bfae12a27..e17945104 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ Components Atmosphère consists of multiple components, each of which replaces/modifies a different component of the system: * Fusée: First-stage Loader, responsible for loading and validating stage 2 (custom TrustZone) plus package2 (Kernel/FIRM sysmodules), and patching them as needed. This replaces all functionality normally in Package1loader/NX Bootloader. - * Sept: Payload used to enable support for runtime key derivation on 7.0.0. * Exosphère: Customized TrustZone, to run a customized Secure Monitor * Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images * Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions diff --git a/atmosphere.mk b/atmosphere.mk index cca6fc106..846ca1c22 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -50,6 +50,7 @@ dist: dist-no-debug cp $(CURRENT_DIRECTORY)/stratosphere/sm/$(ATMOSPHERE_OUT_DIR)/sm.elf $(DIST_DIR)/sm.elf cp $(CURRENT_DIRECTORY)/stratosphere/spl/$(ATMOSPHERE_OUT_DIR)/spl.elf $(DIST_DIR)/spl.elf cp $(CURRENT_DIRECTORY)/stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.elf $(DIST_DIR)/TioServer.elf + cp $(CURRENT_DIRECTORY)/stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.elf $(DIST_DIR)/memlet.elf cp $(CURRENT_DIRECTORY)/troposphere/daybreak/daybreak.elf $(DIST_DIR)/daybreak.elf cp $(CURRENT_DIRECTORY)/troposphere/haze/haze.elf $(DIST_DIR)/haze.elf cp $(CURRENT_DIRECTORY)/troposphere/reboot_to_payload/reboot_to_payload.elf $(DIST_DIR)/reboot_to_payload.elf @@ -87,6 +88,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420 + mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623 @@ -104,6 +106,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp + cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp @build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs rm -r $(DIST_DIR)/stratosphere_romfs cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro diff --git a/config_templates/exosphere.ini b/config_templates/exosphere.ini index e8dc82377..8df772ccf 100644 --- a/config_templates/exosphere.ini +++ b/config_templates/exosphere.ini @@ -1,6 +1,6 @@ # Key: debugmode, default: 1. # Desc: Controls whether kernel is debug mode. -# Disabling this may break Atmosphere's debugger in a future release. +# Disabling this will break Atmosphere. # Key: debugmode_user, default: 0. # Desc: Controls whether userland is debug mode. diff --git a/docs/changelog.md b/docs/changelog.md index ae38d0d70..d498e3242 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,44 @@ # Changelog +## 1.9.0 ++ Basic support was added for 20.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update. + + The same action item from 18.0.0 remains, and I believe in my heart of hearts that it will be addressed eventually. Someone has told me they're working on it. + + There aren't (to my knowledge) outstanding 19.0.0 items any more. + + **Please note**: As a result of changes made to nintendo's software in 20.0.0, there is roughly 10MB less memory available for custom system modules. + + We can only steal a maximum of 14MB from the applet pool, down from 40MB. + + To compensate for this, `ams.mitm`'s heap usage has been reduced by 20MB. + + To facilitate this, a new helper module (`memlet`) was added, so that memory may be temporarily stolen during the romfs building process. + + Hopefully, this results in relatively little breakage, however it is possible that user mods which replace extremely large numbers of files in The Legend of Zelda: Tears of the Kingdom may no longer function. + + If you are affected by this, you will see "Data abort (0x101)" when trying to launch the game with mods. + + Please reach out to `sciresm` on discord if this occurs to share your error report binary. However, some issues may be impossible to fix. + + I apologize sincerely if the issue is impossible to resolve, but I have been forced unavoidably to make compromises here, and I think this is the best balance to be struck. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `loader` was updated to reflect the latest official behavior. + + `pm` was updated to reflect the latest official behavior. + + `ncm` was partially updated to reflect the latest official behavior. + + `erpt` was updated to reflect the latest official behavior. ++ Atmosphère was updated to use GCC 15/newlib (latest devkitA64/devkitARM releases). ++ A number of improvements were made to the dmnt cheat engine. + + New instructions were added, and instructions were updated for improved/new functionality. + + Please see the documents for details -- thanks @tomvita! ++ General system stability improvements to enhance the user's experience. +## 1.8.0 ++ Basic support was added for 19.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update. There is still one action item from 18.0.0 to be addressed, as well. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `loader` was updated to reflect the latest official behavior. + + `pm` was updated to reflect the latest official behavior. + + `ro` was updated to reflect the latest official behavior. ++ `creport`'s file acces patterns were optimized, greatly improving performance when generating a crash report. ++ Atmosphère now uses `relr` relocations where possible. + + This reduces the filesize of a number of atmosphère's modules. ++ A number of minor issues were fixed and improvements were made, including: + + Support was fixed for running Atmosphère on newer units with specific Hynix/Micron DRAM chips. ++ General system stability improvements to enhance the user's experience. ## 1.7.1 + Support was added for 18.1.0. + Atmosphère was updated to use GCC 14/newlib (latest devkitA64/devkitARM releases). diff --git a/docs/features/cheats.md b/docs/features/cheats.md index f67236bba..bf7320f23 100644 --- a/docs/features/cheats.md +++ b/docs/features/cheats.md @@ -49,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address. `0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` + T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to use as an offset from memory region base. + A: Immediate offset to use from memory region base. + V: Value to write. @@ -62,11 +62,13 @@ Code type 0x1 performs a comparison of the contents of memory to a static value. If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped. #### Encoding -`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` +`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` -+ T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + C: Condition to use, see below. ++ X: Operand Type, see below. ++ r: Offset Register (operand types 1). + A: Immediate offset to use from memory region base. + V: Value to compare to. @@ -78,6 +80,9 @@ If the condition is not met, all instructions until the appropriate End or Else + 5: == + 6: != +#### Operand Type ++ 0: Memory Base + Relative Offset ++ 1: Memory Base + Offset Register + Relative Offset --- ### Code Type 0x2: End Conditional Block @@ -126,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR00AA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to load value into. + A: Immediate offset to use from memory region base. @@ -137,6 +142,22 @@ Code type 0x5 allows loading a value from memory into a register, either using a + R: Register to load value into. (This register is also used as the base memory address). + A: Immediate offset to use from register R. +#### Load from Register Address Encoding +`5T0R2SAA AAAAAAAA` + ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ R: Register to load value into. ++ S: Register to use as the base memory address. ++ A: Immediate offset to use from register R. + +#### Load From Fixed Address Encoding with offset register +`5TMR3SAA AAAAAAAA` + ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). ++ R: Register to load value into. ++ S: Register to use as offset register. ++ A: Immediate offset to use from memory region base. --- ### Code Type 0x6: Store Static Value to Register Memory Address @@ -250,7 +271,10 @@ Code type 0x9 allows performing arithmetic on registers. + 7: Logical Not (discards right-hand operand) + 8: Logical Xor + 9: None/Move (discards right-hand operand) - ++ 10: Float Addition, T==4 single T==8 double ++ 11: Float Subtraction, T==4 single T==8 double ++ 12: Float Multiplication, T==4 single T==8 double ++ 13: Float Division, T==4 single T==8 double --- ### Code Type 0xA: Store Register to Memory Address @@ -380,6 +404,61 @@ Code type 0xC3 reads or writes a static register with a given register. --- +### Code Type 0xC4: Begin Extended Keypress Conditional Block +Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed. + +#### Encoding +`C4r00000 kkkkkkkk kkkkkkkk` + ++ r: Auto-repeat, see below. ++ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`. + +Note that for multiple button combinations, the bitmasks should be OR'd together. + +#### Auto-repeat + ++ 0: The conditional block executes only once when the keypad mask matches. The mask must stop matching to reset for the next trigger. ++ 1: The conditional block executes as long as the keypad mask matches. + +#### Keypad Values +Note: This is the direct output of `hidKeysDown()`. + ++ 000000001: A ++ 000000002: B ++ 000000004: X ++ 000000008: Y ++ 000000010: Left Stick Pressed ++ 000000020: Right Stick Pressed ++ 000000040: L ++ 000000080: R ++ 000000100: ZL ++ 000000200: ZR ++ 000000400: Plus ++ 000000800: Minus ++ 000001000: Left ++ 000002000: Up ++ 000004000: Right ++ 000008000: Down ++ 000010000: Left Stick Left ++ 000020000: Left Stick Up ++ 000040000: Left Stick Right ++ 000080000: Left Stick Down ++ 000100000: Right Stick Left ++ 000200000: Right Stick Up ++ 000400000: Right Stick Right ++ 000800000: Right Stick Down ++ 001000000: SL Left Joy-Con ++ 002000000: SR Left Joy-Con ++ 004000000: SL Right Joy-Con ++ 008000000: SR Right Joy-Con ++ 010000000: Top button on Poké Ball Plus (Palma) controller ++ 020000000: Verification ++ 040000000: B button on Left NES/HVC controller in Handheld mode ++ 080000000: Left C button in N64 controller ++ 100000000: Up C button in N64 controller ++ 200000000: Right C button in N64 controller ++ 400000000: Down C button in N64 controller + ### Code Type 0xF0: Double Extended-Width Instruction Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble. diff --git a/emummc/.gitrepo b/emummc/.gitrepo index f4eb810eb..69247ebe9 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = f23f943d4092ca9490dbcebbdd117abc3740abcf - parent = 1e3349e99a023517269b3fc1bc32fd84e5b3caa9 + commit = 7522f1f6054a71bdff5beadee0302cead1235be3 + parent = 0e2ef545f947d24c6add254874ab493ba84bbdc9 method = merge cmdver = 0.4.1 diff --git a/emummc/README.md b/emummc/README.md index f01783ba5..ea9a91d7c 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 18.1.0** +**1.0.0 - 20.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index b2059c092..3ceca0f8e 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -73,6 +73,10 @@ #include "offsets/1800_exfat.h" #include "offsets/1810.h" #include "offsets/1810_exfat.h" +#include "offsets/1900.h" +#include "offsets/1900_exfat.h" +#include "offsets/2000.h" +#include "offsets/2000_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -157,6 +161,10 @@ DEFINE_OFFSET_STRUCT(_1800); DEFINE_OFFSET_STRUCT(_1800_EXFAT); DEFINE_OFFSET_STRUCT(_1810); DEFINE_OFFSET_STRUCT(_1810_EXFAT); +DEFINE_OFFSET_STRUCT(_1900); +DEFINE_OFFSET_STRUCT(_1900_EXFAT); +DEFINE_OFFSET_STRUCT(_2000); +DEFINE_OFFSET_STRUCT(_2000_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -274,6 +282,14 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1810)); case FS_VER_18_1_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1810_EXFAT)); + case FS_VER_19_0_0: + return &(GET_OFFSET_STRUCT_NAME(_1900)); + case FS_VER_19_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_1900_EXFAT)); + case FS_VER_20_0_0: + return &(GET_OFFSET_STRUCT_NAME(_2000)); + case FS_VER_20_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index ec4f9ecf8..5b2dfc508 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -107,6 +107,12 @@ enum FS_VER FS_VER_18_1_0, FS_VER_18_1_0_EXFAT, + FS_VER_19_0_0, + FS_VER_19_0_0_EXFAT, + + FS_VER_20_0_0, + FS_VER_20_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1900.h b/emummc/source/FS/offsets/1900.h new file mode 100644 index 000000000..82ffd0f94 --- /dev/null +++ b/emummc/source/FS/offsets/1900.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * 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 . + */ +#ifndef __FS_1900_H__ +#define __FS_1900_H__ + +// Accessor vtable getters +#define FS_OFFSET_1900_SDMMC_ACCESSOR_GC 0x195C00 +#define FS_OFFSET_1900_SDMMC_ACCESSOR_SD 0x197F80 +#define FS_OFFSET_1900_SDMMC_ACCESSOR_NAND 0x1963B0 + +// Hooks +#define FS_OFFSET_1900_SDMMC_WRAPPER_READ 0x191A70 +#define FS_OFFSET_1900_SDMMC_WRAPPER_WRITE 0x191AD0 +#define FS_OFFSET_1900_RTLD 0x275F0 +#define FS_OFFSET_1900_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x50))) + +#define FS_OFFSET_1900_CLKRST_SET_MIN_V_CLK_RATE 0x1B3880 + +// Misc funcs +#define FS_OFFSET_1900_LOCK_MUTEX 0x18AC20 +#define FS_OFFSET_1900_UNLOCK_MUTEX 0x18AC70 + +#define FS_OFFSET_1900_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191A30 +#define FS_OFFSET_1900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191A50 + +// Misc Data +#define FS_OFFSET_1900_SD_MUTEX 0xFE1408 +#define FS_OFFSET_1900_NAND_MUTEX 0xFDCB60 +#define FS_OFFSET_1900_ACTIVE_PARTITION 0xFDCBA0 +#define FS_OFFSET_1900_SDMMC_DAS_HANDLE 0xFC1908 + +// NOPs +#define FS_OFFSET_1900_SD_DAS_INIT 0x260C4 + +// Nintendo Paths +#define FS_OFFSET_1900_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00067FC8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00075D6C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007D1E8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00092818, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1900_H__ diff --git a/emummc/source/FS/offsets/1900_exfat.h b/emummc/source/FS/offsets/1900_exfat.h new file mode 100644 index 000000000..2bbf0c899 --- /dev/null +++ b/emummc/source/FS/offsets/1900_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * 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 . + */ +#ifndef __FS_1900_EXFAT_H__ +#define __FS_1900_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_GC 0x1A1430 +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_SD 0x1A37B0 +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_NAND 0x1A1BE0 + +// Hooks +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_READ 0x19D2A0 +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_WRITE 0x19D300 +#define FS_OFFSET_1900_EXFAT_RTLD 0x275F0 +#define FS_OFFSET_1900_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x50))) + +#define FS_OFFSET_1900_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1BF0B0 + +// Misc funcs +#define FS_OFFSET_1900_EXFAT_LOCK_MUTEX 0x196450 +#define FS_OFFSET_1900_EXFAT_UNLOCK_MUTEX 0x1964A0 + +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x19D260 +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x19D280 + +// Misc Data +#define FS_OFFSET_1900_EXFAT_SD_MUTEX 0xFF4408 +#define FS_OFFSET_1900_EXFAT_NAND_MUTEX 0xFEFB60 +#define FS_OFFSET_1900_EXFAT_ACTIVE_PARTITION 0xFEFBA0 +#define FS_OFFSET_1900_EXFAT_SDMMC_DAS_HANDLE 0xFCF908 + +// NOPs +#define FS_OFFSET_1900_EXFAT_SD_DAS_INIT 0x260C4 + +// Nintendo Paths +#define FS_OFFSET_1900_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00067FC8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00075D6C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007D1E8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00092818, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1900_EXFAT_H__ diff --git a/emummc/source/FS/offsets/2000.h b/emummc/source/FS/offsets/2000.h new file mode 100644 index 000000000..b4fe302d7 --- /dev/null +++ b/emummc/source/FS/offsets/2000.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * 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 . + */ +#ifndef __FS_2000_H__ +#define __FS_2000_H__ + +// Accessor vtable getters +#define FS_OFFSET_2000_SDMMC_ACCESSOR_GC 0x1A7DB0 +#define FS_OFFSET_2000_SDMMC_ACCESSOR_SD 0x1AA130 +#define FS_OFFSET_2000_SDMMC_ACCESSOR_NAND 0x1A8560 + +// Hooks +#define FS_OFFSET_2000_SDMMC_WRAPPER_READ 0x1A3C20 +#define FS_OFFSET_2000_SDMMC_WRAPPER_WRITE 0x1A3C80 +#define FS_OFFSET_2000_RTLD 0x2B594 +#define FS_OFFSET_2000_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2000_CLKRST_SET_MIN_V_CLK_RATE 0x1C6150 + +// Misc funcs +#define FS_OFFSET_2000_LOCK_MUTEX 0x19CD80 +#define FS_OFFSET_2000_UNLOCK_MUTEX 0x19CDD0 + +#define FS_OFFSET_2000_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A3BE0 +#define FS_OFFSET_2000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A3C00 + +// Misc Data +#define FS_OFFSET_2000_SD_MUTEX 0xFF5408 +#define FS_OFFSET_2000_NAND_MUTEX 0xFF0CF0 +#define FS_OFFSET_2000_ACTIVE_PARTITION 0xFF0D30 +#define FS_OFFSET_2000_SDMMC_DAS_HANDLE 0xFD2B08 + +// NOPs +#define FS_OFFSET_2000_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2000_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2000_H__ diff --git a/emummc/source/FS/offsets/2000_exfat.h b/emummc/source/FS/offsets/2000_exfat.h new file mode 100644 index 000000000..a8245a2a7 --- /dev/null +++ b/emummc/source/FS/offsets/2000_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * 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 . + */ +#ifndef __FS_2000_EXFAT_H__ +#define __FS_2000_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_GC 0x1B36D0 +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_SD 0x1B5A50 +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_NAND 0x1B3E80 + +// Hooks +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_READ 0x1AF540 +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_WRITE 0x1AF5A0 +#define FS_OFFSET_2000_EXFAT_RTLD 0x2B594 +#define FS_OFFSET_2000_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2000_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D1A70 + +// Misc funcs +#define FS_OFFSET_2000_EXFAT_LOCK_MUTEX 0x1A86A0 +#define FS_OFFSET_2000_EXFAT_UNLOCK_MUTEX 0x1A86F0 + +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500 +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF520 + +// Misc Data +#define FS_OFFSET_2000_EXFAT_SD_MUTEX 0x1006408 +#define FS_OFFSET_2000_EXFAT_NAND_MUTEX 0x1001CF0 +#define FS_OFFSET_2000_EXFAT_ACTIVE_PARTITION 0x1001D30 +#define FS_OFFSET_2000_EXFAT_SDMMC_DAS_HANDLE 0xFDFB08 + +// NOPs +#define FS_OFFSET_2000_EXFAT_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2000_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2000_EXFAT_H__ diff --git a/emummc/source/utils/types.h b/emummc/source/utils/types.h index ce4db820c..42bb1fad9 100644 --- a/emummc/source/utils/types.h +++ b/emummc/source/utils/types.h @@ -18,6 +18,7 @@ #define _TYPES_H_ #include +#include #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -58,12 +59,6 @@ typedef u32 Result; ///< Function error code result type. #define INVALID_HANDLE ((Handle) 0) #define CUR_PROCESS_HANDLE ((Handle) 0xFFFF8001) -#ifndef __cplusplus -typedef int bool; -#define true 1 -#define false 0 -#endif /* __cplusplus */ - #define BOOT_CFG_AUTOBOOT_EN (1 << 0) #define BOOT_CFG_FROM_LAUNCH (1 << 1) #define BOOT_CFG_SEPT_RUN (1 << 7) diff --git a/exosphere/loader_stub/loader_stub.mk b/exosphere/loader_stub/loader_stub.mk index df737a370..7bffe7dc0 100644 --- a/exosphere/loader_stub/loader_stub.mk +++ b/exosphere/loader_stub/loader_stub.mk @@ -15,13 +15,12 @@ ifneq ($(__RECURSIVE__),1) export ATMOSPHERE_TOPDIR := $(CURRENT_DIRECTORY) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ - $(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) -BINFILES := program.lz4 boot_code.lz4 +BINFILES := #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -102,13 +101,7 @@ $(OUTPUT).elf : $(OFILES) $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a -program.lz4.o: program.lz4 - @echo $(notdir $<) - @$(bin2o) - -boot_code.lz4.o: boot_code.lz4 - @echo $(notdir $<) - @$(bin2o) +secmon_loader_main.o: CXXFLAGS += --embed-dir="$(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR)/" %.elf: @echo linking $(notdir $@) @@ -117,14 +110,6 @@ boot_code.lz4.o: boot_code.lz4 $(OFILES_SRC) : $(OFILES_BIN) -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -%.bin.o %_bin.h: %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -include $(DEPENDS) #--------------------------------------------------------------------------------------- diff --git a/exosphere/loader_stub/source/secmon_loader_main.cpp b/exosphere/loader_stub/source/secmon_loader_main.cpp index 368941eb1..782d7ac11 100644 --- a/exosphere/loader_stub/source/secmon_loader_main.cpp +++ b/exosphere/loader_stub/source/secmon_loader_main.cpp @@ -15,21 +15,31 @@ */ #include #include "secmon_loader_uncompress.hpp" -#include "program_lz4.h" -#include "boot_code_lz4.h" namespace ams::secmon::loader { - NORETURN void UncompressAndExecute(const void *program, const void *boot_code) { + namespace { + + constexpr const u8 SecmonProgramLz4[] = { + #embed + }; + + constexpr const u8 SecmonBootCodeLz4[] = { + #embed + }; + + } + + NORETURN void UncompressAndExecute() { /* Uncompress the program image. */ - Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size); + Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), SecmonProgramLz4, sizeof(SecmonProgramLz4)); /* Copy the boot image to the end of IRAM */ - u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - boot_code_lz4_size; - std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size); + u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - sizeof(SecmonBootCodeLz4); + std::memcpy(relocated_boot_code, SecmonBootCodeLz4, sizeof(SecmonBootCodeLz4)); /* Uncompress the boot image. */ - Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size); + Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, sizeof(SecmonBootCodeLz4)); /* Jump to the boot image. */ reinterpret_cast(secmon::MemoryRegionPhysicalIramBootCodeImage.GetAddress())(); diff --git a/exosphere/loader_stub/source/start.s b/exosphere/loader_stub/source/start.s index 47838e5fa..6640ac2d9 100644 --- a/exosphere/loader_stub/source/start.s +++ b/exosphere/loader_stub/source/start.s @@ -98,8 +98,5 @@ _start: ldr x20, =0x7C020000 mov sp, x20 - adr x0, program_lz4 - adr x1, boot_code_lz4 - /* Uncompress the program and iram boot code images. */ - b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_ + b _ZN3ams6secmon6loader20UncompressAndExecuteEv diff --git a/exosphere/program/program.ld b/exosphere/program/program.ld index f0ec57a71..2cbd831ef 100644 --- a/exosphere/program/program.ld +++ b/exosphere/program/program.ld @@ -106,6 +106,7 @@ SECTIONS .debug_code : { KEEP (*(.text._ZN3ams3log6PrintfEPKcz .text._ZN3ams3log7VPrintfEPKcSt9__va_list .text._ZN3ams3log4DumpEPKvm)) KEEP (*(.text._ZN3ams4util10TVSNPrintfEPcmPKcSt9__va_list .text._ZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE3_clEbm)) + KEEP (*(.text._ZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE_clEbm)) KEEP(secmon_exception_handler.o(.text*)) secmon_exception_handler.o(.rodata*) secmon_exception_handler.o(.data*) diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index b745114f1..5ff3809d0 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED +.byte 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 /* Mariko Production Master Kek Source. */ -.byte 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 +.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -109,6 +109,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 /* Master key 0E encrypted with Master key 0F. */ .byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */ .byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */ +.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */ +.byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -129,6 +131,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 /* Master key 0E encrypted with Master key 0F. */ .byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */ .byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */ +.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */ +.byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -146,6 +150,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C /* 16.0.0 Device Master Key Source Source. */ .byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */ .byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */ +.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */ +.byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -163,6 +169,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F /* 16.0.0 Device Master Kek Source. */ .byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */ .byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */ +.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */ +.byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -180,3 +188,5 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F /* 16.0.0 Device Master Kek Source. */ .byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ .byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */ +.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */ +.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */ \ No newline at end of file diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index a51e1a712..88c8f1189 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 18); + static_assert(pkg1::KeyGeneration_Count == 20); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 index 0d8bf42d6..73e792fb2 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/1.lz4 index d8e7c5a10..73dba658a 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/2.lz4 index 3a969c703..d66625045 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 index e3b2cf75d..42e1d924d 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 index 9e279a5f5..974d69d9c 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/5.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/5.lz4 index 0c00bd2d8..ff84fafe5 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/5.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/5.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 index 67a3ddd58..915757ed9 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 index 9514bc894..35af29230 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/8.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/8.lz4 index 72671a6c6..cc856bb57 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/8.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/8.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/9.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/9.lz4 index a1bf88e91..616e4bef7 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/9.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/9.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/0.lz4 index 3b2d9622b..c51e46b47 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 index 97fe2d33f..486fa90e1 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/2.lz4 index ee0cb2dd0..223760ad7 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/3.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/3.lz4 index 594bda5fe..a022021e0 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/3.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/3.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 index 335d29514..3ec06a3f4 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/5.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/5.lz4 index 1b1b28d40..cdd389bd6 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/5.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/5.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 index 488f98812..34f639ba5 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 index 50f00c13a..fdf298bb7 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/8.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/8.lz4 index 5fe95de28..386f938aa 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/8.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/8.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/9.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/9.lz4 index 8c1df89e8..864a18271 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/9.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/9.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/0.lz4 index 3b2d9622b..c51e46b47 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 index 97fe2d33f..486fa90e1 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/2.lz4 index ee0cb2dd0..223760ad7 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/3.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/3.lz4 index 594bda5fe..a022021e0 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/3.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/3.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 index 335d29514..3ec06a3f4 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/5.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/5.lz4 index 1b1b28d40..cdd389bd6 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/5.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/5.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 index 488f98812..34f639ba5 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 index 50f00c13a..fdf298bb7 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/8.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/8.lz4 index 5fe95de28..386f938aa 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/8.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/8.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/9.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/9.lz4 index 8c1df89e8..864a18271 100644 Binary files a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/9.lz4 and b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/9.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 index 53d794d01..b757e62d8 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 index c32abfc77..4e58de4e3 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 index b97594bc0..a29874bd9 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 index cadd417f1..205fdbb7b 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/1.lz4 index 80af9d717..3c6929d62 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/2.lz4 index d2768055f..e6c956917 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/0.lz4 index f3a8aca25..f13389e5f 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 index 6d2f2ef86..804393160 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 index 3ab45f9f1..0fa57ea67 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 index cadd417f1..205fdbb7b 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 index 80af9d717..3c6929d62 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 index b3ad2304e..42aa35419 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 index a8fdf10ed..3f6041a27 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 index c5ad29b66..b27ed15a4 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 index 3324c9e8f..f47ee2bf8 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 index db56a6486..4df1465fa 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 index 6cfeb96f4..774411526 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 index 9df00662a..cee1a8a17 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 index ffe64ed60..8188217e0 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/1.lz4 index 768280006..1269d9878 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/2.lz4 index 185141180..8943ef137 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/0.lz4 index f0f784841..c143b846c 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 index ec6b7aea0..27f2b519d 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 index 82a720acc..18423acef 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 index 9aa35bb1b..5baad7694 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 index 14d7f1b44..e6ef1f317 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 index 631e92868..228a120f8 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 index 260bf3d32..718241df0 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/1.lz4 index 10595c50e..f24dd27d4 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 index a97114e27..e9c0433ab 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/0.lz4 index 8abd28956..f349fa566 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/1.lz4 index e758fde99..8a270c4ab 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 index 3cffc39d9..f11e07bcd 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/0.lz4 index 6d1500d7e..97f963ec6 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/1.lz4 index dfd43b94a..986ec2635 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 index 29f33852f..74be6d5d3 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/0.lz4 index 53d794d01..b757e62d8 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/1.lz4 index c32abfc77..4e58de4e3 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/2.lz4 index b97594bc0..a29874bd9 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1z4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/0.lz4 index a9fc86afa..361da04ad 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 index 71da3eed0..cfd755d17 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 index 96ff15438..410239cf6 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 index f3a8aca25..f13389e5f 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 index 1022eb947..a92171989 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 index ed395cd54..c4de070ce 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 index f72bb75eb..0193ce8cf 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 index b3b510aa2..2b1c83884 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 index d04e69a2e..e2eec4ee3 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 index 369a4d7b8..0e027354c 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/1.lz4 index 92410ca3f..e490e03f1 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/1.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/1.lz4 differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/2.lz4 index d3ebf31a8..a6614cce0 100644 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/2.lz4 and b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/2.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_0_1.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_0_1.lz4 index 846b0fba7..5aa1ea39b 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_erista_0_1.lz4 and b/fusee/program/sdram_params/lz/sdram_params_erista_0_1.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 index a8de51bea..2a47d2537 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 and b/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_4_5.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_4_5.lz4 index ac73ca087..9e22b4421 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_erista_4_5.lz4 and b/fusee/program/sdram_params/lz/sdram_params_erista_4_5.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 index 6a0fa56ac..b0402b601 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 and b/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 index b7ea6f320..2ff9fd5fd 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_10_11.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_10_11.lz4 index 3081ab081..f4a26bfac 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_10_11.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_10_11.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_12_13.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_12_13.lz4 index 0a8217241..ebc0d3029 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_12_13.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_12_13.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 index fe9645121..d3cd2126c 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 index 12c1e6a19..7392208b6 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 index c03d9f26a..a1aa66a4c 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 differ diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_8_9.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_8_9.lz4 index 37e142b08..287d51c75 100644 Binary files a/fusee/program/sdram_params/lz/sdram_params_mariko_8_9.lz4 and b/fusee/program/sdram_params/lz/sdram_params_mariko_8_9.lz4 differ diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index cad7ca589..bca7c4e9b 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 + 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED + 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 + 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -72,6 +72,8 @@ namespace ams::nxboot { { 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, /* 16.0.0 Device Master Key Source Source. */ { 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */ { 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */ + { 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */ + { 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -90,6 +92,8 @@ namespace ams::nxboot { { 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, /* 16.0.0 Device Master Kek Source. */ { 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */ { 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */ + { 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */ + { 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -108,6 +112,8 @@ namespace ams::nxboot { { 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F }, /* 16.0.0 Device Master Kek Source. */ { 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */ { 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */ + { 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */ + { 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -129,6 +135,8 @@ namespace ams::nxboot { { 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, /* Master key 0E encrypted with Master key 0F. */ { 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */ { 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */ + { 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */ + { 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -150,6 +158,8 @@ namespace ams::nxboot { { 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 }, /* Master key 0E encrypted with Master key 0F. */ { 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */ { 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */ + { 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */ + { 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index 535f0f68d..3a75a043f 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 18); + static_assert(pkg1::KeyGeneration_Count == 20); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 78c40b216..000bbe524 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -261,6 +261,10 @@ namespace ams::nxboot { return ams::TargetFirmware_17_0_0; } else if (std::memcmp(package1 + 0x10, "20240207", 8) == 0) { return ams::TargetFirmware_18_0_0; + } else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) { + return ams::TargetFirmware_19_0_0; + } else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) { + return ams::TargetFirmware_20_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index e002649b4..34134ff42 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -177,6 +177,12 @@ namespace ams::nxboot { FsVersion_18_1_0, FsVersion_18_1_0_Exfat, + FsVersion_19_0_0, + FsVersion_19_0_0_Exfat, + + FsVersion_20_0_0, + FsVersion_20_0_0_Exfat, + FsVersion_Count, }; @@ -266,6 +272,12 @@ namespace ams::nxboot { { 0xA3, 0x39, 0xF0, 0x1C, 0x95, 0xBF, 0xA7, 0x68 }, /* FsVersion_18_1_0 */ { 0x20, 0x4C, 0xBA, 0x86, 0xDE, 0x08, 0x44, 0x6A }, /* FsVersion_18_1_0_Exfat */ + + { 0xD9, 0x4C, 0x68, 0x15, 0xF8, 0xF5, 0x0A, 0x20 }, /* FsVersion_19_0_0 */ + { 0xED, 0xA8, 0x78, 0x68, 0xA4, 0x49, 0x07, 0x50 }, /* FsVersion_19_0_0_Exfat */ + + { 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */ + { 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -485,233 +497,6 @@ namespace ams::nxboot { 0xE0, 0x03, 0x1F, 0x2A, 0xC0, 0x03, 0x5F, 0xD6, }; - constexpr const u8 NoNcaHeaderSignatureCheckPatch0[] = { - 0x1F, 0x20, 0x03, 0xD5, - }; - - constexpr const u8 NoNcaHeaderSignatureCheckPatch1[] = { - 0xE0, 0x03, 0x1F, 0x2A, - }; - - constexpr const u8 NoNcaHeaderSignatureCheckPatch2[] = { - 0x1E, 0x00, 0x00, 0x14, - }; - - void AddNoNcaHeaderSignatureCheckPatches(InitialProcessMeta *fs_meta, FsVersion fs_version) { - switch (fs_version) { - case FsVersion_1_0_0: - AddPatch(fs_meta, 0x019568, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0195A0, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x031208, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x03A89C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_2_0_0: - case FsVersion_2_0_0_Exfat: - AddPatch(fs_meta, 0x015E5C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x015EF4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x032C30, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x03F820, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_2_1_0: - case FsVersion_2_1_0_Exfat: - AddPatch(fs_meta, 0x015FCC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x016064, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x033008, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x03FBF8, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_3_0_0: - case FsVersion_3_0_0_Exfat: - AddPatch(fs_meta, 0x018E8C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x018F24, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0374BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x049FC8, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_3_0_1: - case FsVersion_3_0_1_Exfat: - AddPatch(fs_meta, 0x018EF8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x018F90, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x037528, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x04A034, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_4_0_0: - case FsVersion_4_0_0_Exfat: - AddPatch(fs_meta, 0x01C564, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x01C5FC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x01E1DC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x057A34, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_4_1_0: - case FsVersion_4_1_0_Exfat: - AddPatch(fs_meta, 0x01C564, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x01C5FC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x01E1DC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x057A34, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_5_0_0: - case FsVersion_5_0_0_Exfat: - AddPatch(fs_meta, 0x022E68, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x022EDC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0259C4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07D590, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_5_1_0: - case FsVersion_5_1_0_Exfat: - AddPatch(fs_meta, 0x022E98, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x022F0C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0259F4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07D960, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_6_0_0: - AddPatch(fs_meta, 0x071334, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0713A8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x081884, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0EB18C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_6_0_0_Exfat: - AddPatch(fs_meta, 0x07CA34, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07CAA8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x081884, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0F688C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_7_0_0: - AddPatch(fs_meta, 0x074AF4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x074B2C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07A968, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0F26E4, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_7_0_0_Exfat: - AddPatch(fs_meta, 0x0800A4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0800DC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x085F18, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0FDC94, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_8_0_0: - AddPatch(fs_meta, 0x0763D4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07640C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07C4C8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0F4AA4, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_8_1_0: - AddPatch(fs_meta, 0x0763D4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07640C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x07C4C8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0F4AA4, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_8_0_0_Exfat: - AddPatch(fs_meta, 0x081984, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0819BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x087A78, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x100054, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_8_1_0_Exfat: - AddPatch(fs_meta, 0x081984, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0819BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x087A78, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x100054, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_9_0_0: - case FsVersion_9_0_0_Exfat: - AddPatch(fs_meta, 0x061F54, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x061F8C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0679DC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0CA140, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_9_1_0: - case FsVersion_9_1_0_Exfat: - AddPatch(fs_meta, 0x061F64, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x061F9C, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0679EC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0CA150, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_10_0_0: - case FsVersion_10_0_0_Exfat: - AddPatch(fs_meta, 0x0774BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0DC120, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_10_2_0: - case FsVersion_10_2_0_Exfat: - AddPatch(fs_meta, 0x0774BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0DC580, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_11_0_0: - case FsVersion_11_0_0_Exfat: - AddPatch(fs_meta, 0x079378, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0E3014, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_12_0_0: - case FsVersion_12_0_0_Exfat: - AddPatch(fs_meta, 0x07A020, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0EBE28, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_12_0_3: - case FsVersion_12_0_3_Exfat: - AddPatch(fs_meta, 0x07A130, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0EBF38, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - case FsVersion_13_0_0: - case FsVersion_13_0_0_Exfat: - AddPatch(fs_meta, 0x07AFC8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0EF420, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_13_1_0: - case FsVersion_13_1_0_Exfat: - AddPatch(fs_meta, 0x07AFC8, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x0EF420, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_14_0_0: - AddPatch(fs_meta, 0x079D00, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x1282CC, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_14_0_0_Exfat: - AddPatch(fs_meta, 0x079D00, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x13364C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_15_0_0: - AddPatch(fs_meta, 0x06ECA4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x120EEC, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_15_0_0_Exfat: - AddPatch(fs_meta, 0x06ECA4, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x12BE7C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_16_0_0: - AddPatch(fs_meta, 0x06F804, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x148C2C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_16_0_0_Exfat: - AddPatch(fs_meta, 0x06F804, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x15390C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_16_0_3: - AddPatch(fs_meta, 0x06F854, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x148C7C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_16_0_3_Exfat: - AddPatch(fs_meta, 0x06F854, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x15385C, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - break; - case FsVersion_17_0_0: - case FsVersion_17_0_0_Exfat: - AddPatch(fs_meta, 0x024254, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - AddPatch(fs_meta, 0x073C04, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - break; - case FsVersion_18_0_0: - case FsVersion_18_0_0_Exfat: - case FsVersion_18_1_0: - case FsVersion_18_1_0_Exfat: - AddPatch(fs_meta, 0x0246F4, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - AddPatch(fs_meta, 0x0744BC, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - break; - case FsVersion_19_0_0: - case FsVersion_19_0_0_Exfat: - AddPatch(fs_meta, 0x021578, NoNcaHeaderSignatureCheckPatch0, sizeof(NoNcaHeaderSignatureCheckPatch0)); - AddPatch(fs_meta, 0x0746A0, NoNcaHeaderSignatureCheckPatch1, sizeof(NoNcaHeaderSignatureCheckPatch1)); - AddPatch(fs_meta, 0x074624, NoNcaHeaderSignatureCheckPatch2, sizeof(NoNcaHeaderSignatureCheckPatch2)); - break; - default: - break; - } - } - void AddNogcPatches(InitialProcessMeta *fs_meta, FsVersion fs_version) { switch (fs_version) { case FsVersion_1_0_0: @@ -872,6 +657,26 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_19_0_0: + AddPatch(fs_meta, 0x195C75, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x195E75, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x16F170, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_19_0_0_Exfat: + AddPatch(fs_meta, 0x1A14A5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1A16A5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_20_0_0: + AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_20_0_0_Exfat: + AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } @@ -1064,8 +869,6 @@ namespace ams::nxboot { AddNogcPatches(fs_meta, fs_version); } - AddNoNcaHeaderSignatureCheckPatches(fs_meta, fs_version); - /* TODO ams.tma2: add mount_host patches. */ } diff --git a/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc b/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc index 56f8574ca..9e36044f7 100644 --- a/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc +++ b/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc @@ -421,6 +421,7 @@ constexpr const u8 EmcRamTrainingPatternData[] { 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03 }; +static_assert(sizeof(EmcRamTrainingPatternData) % sizeof(EmcRamTrainingPattern) == 0); ALWAYS_INLINE const EmcRamTrainingPattern *GetEmcRamTrainingPattern() { return reinterpret_cast(EmcRamTrainingPatternData); diff --git a/fusee/program/source/mtc/fusee_mtc_tables_erista.inc b/fusee/program/source/mtc/fusee_mtc_tables_erista.inc index 5d3296c59..6fc664d4d 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_erista.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_erista.inc @@ -14,2784 +14,15 @@ * along with this program. If not, see . */ -constexpr const u8 T210SdevEmcDvfsTableS6gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 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, 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, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xD0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 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, 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, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 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, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 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, 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, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableS6gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin" }; -constexpr const u8 T210SdevEmcDvfsTableH4gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 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, 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, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xD0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 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, 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, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x04, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 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, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x2B, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 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, 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, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableH4gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin" }; -constexpr const u8 T210SdevEmcDvfsTableS4gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 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, 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, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xD0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 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, 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, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 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, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 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, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 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, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 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, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 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, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 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, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 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, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 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, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 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, 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, 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, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 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, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 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, - 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, 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, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 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, 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, 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, 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, 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, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 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, 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, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableS4gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin" }; diff --git a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc index 83b06e808..de7f89dfb 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc @@ -14,1830 +14,71 @@ * along with this program. If not, see . */ -constexpr const u8 T210b01SdevEmcDvfsTableM4gb03[0x681] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, - 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, - 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x2A, 0x64, 0x00, 0x57, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, - 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, - 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xD3, 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, - 0x88, 0x01, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, - 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, - 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, - 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, - 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, - 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, - 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, - 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, - 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, - 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, - 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, - 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, - 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, - 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, - 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, - 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, - 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, - 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, - 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, - 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, - 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, - 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, - 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, - 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, - 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x00, 0x48, 0x00, 0x04, 0x45, 0x14, 0x13, 0x2F, 0x08, 0x00, - 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, - 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0A, 0x0B, 0x88, 0x22, 0x00, - 0x0E, 0x00, 0x10, 0x00, 0x1B, 0x00, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47, 0x00, - 0x49, 0x00, 0x47, 0x00, 0x46, 0xB0, 0x00, 0x3F, 0x00, 0x00, 0x10, 0x18, 0x00, 0x06, 0x20, 0x22, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x4F, 0x1B, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0xB0, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0xA0, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, - 0x04, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, - 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, - 0x06, 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, - 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, - 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, - 0x02, 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, - 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, - 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, - 0x00, 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, - 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, - 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, - 0x64, 0x2C, 0x00, 0x07, 0x20, 0x80, 0x18, 0x3F, 0x01, 0x3F, 0x00, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x2A, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, - 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, - 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, - 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, - 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, - 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, - 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, - 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, - 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD5, - 0x06, 0x06, 0x0B, 0x88, 0x15, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0A, 0x90, 0x0A, 0x33, - 0x02, 0x00, 0x07, 0x48, 0x03, 0x00, 0xFA, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, 0x15, 0x00, 0x3A, - 0x00, 0x11, 0x09, 0x22, 0x00, 0x00, 0x90, 0x09, 0x1F, 0x15, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, - 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, - 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, - 0x0D, 0x05, 0x21, 0x00, 0x06, 0x23, 0x01, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, - 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, - 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, - 0x33, 0xA4, 0x0C, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, - 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, - 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, - 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, - 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, - 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, - 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x2B, 0x00, 0x24, 0x00, 0x28, - 0x00, 0x20, 0x00, 0x29, 0x00, 0x26, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, - 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, - 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, - 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, - 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, - 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, - 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, - 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, - 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, - 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, - 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, - 0x02, 0x0C, 0x00, 0x00, 0x48, 0x00, 0x04, 0x45, 0x14, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, - 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x04, - 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, - 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, - 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, - 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, - 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, - 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, - 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, - 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, - 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, - 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, - 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, - 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, - 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, - 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, - 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, - 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, - 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, - 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, - 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, - 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, - 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, - 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, - 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x08, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, - 0x00, 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, - 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, - 0x16, 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, - 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, - 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, - 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, - 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, - 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, - 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, - 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x17, 0x02, 0x0C, 0x06, 0x1B, - 0x01, 0xFC, 0x05, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, 0x03, - 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, - 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, - 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, - 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, 0xEC, - 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, - 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x8C, 0x09, - 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, - 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, - 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, - 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, - 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x08, 0x0E, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0E, 0x00, - 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, - 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, 0x8C, 0x09, 0xA0, - 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, - 0x12, 0x61, 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, - 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, - 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, - 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, - 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, - 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, - 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, - 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, - 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, - 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, - 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0xA8, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, - 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, - 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, - 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, - 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, - 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, - 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, - 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, - 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, - 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[0x679] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, - 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, - 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, - 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, - 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, - 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, - 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, - 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, - 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, - 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, - 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, - 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, - 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, - 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, - 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, - 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00, - 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, - 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, - 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, - 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, - 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, - 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, - 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, - 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, - 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, - 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, - 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, - 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, - 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, - 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, - 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, - 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, - 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, - 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, - 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, - 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12, - 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, - 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, - 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, - 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, - 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, - 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, - 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, - 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, - 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, - 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, - 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, - 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, - 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, - 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, - 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, - 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, - 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, - 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, - 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, - 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, - 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, - 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, - 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, - 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, 0x00, - 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, - 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, - 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, - 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, - 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, - 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, - 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, - 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, - 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, - 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, - 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, - 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, - 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, - 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, - 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD3, 0x06, 0x06, - 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, 0x88, 0x01, 0x13, 0x03, 0xC0, - 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, - 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, - 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, - 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, - 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, - 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, - 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, - 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, - 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, - 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, - 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, - 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, - 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, - 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, - 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, - 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, - 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, - 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, - 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, - 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[0x67D] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, - 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, - 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, - 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, - 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, - 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, - 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, - 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, - 0x00, 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, - 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, - 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, - 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, - 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, - 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, - 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, - 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, - 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, - 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, - 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, - 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, - 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, - 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, - 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, - 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, - 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, - 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, - 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, - 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, - 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, - 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, - 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, - 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, - 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, - 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, - 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, - 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, - 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, - 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, - 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, - 0x02, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, - 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, - 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, - 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, - 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, - 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, - 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, - 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, - 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, - 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, - 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, - 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, - 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, - 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableM1y4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, - 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, - 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, - 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, - 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, - 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, - 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, - 0x09, 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, - 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, - 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, - 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, - 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, - 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, - 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, - 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, - 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, - 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, - 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, - 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, - 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, - 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, - 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, - 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, - 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, - 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, - 0x1D, 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, - 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, - 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, - 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, - 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, - 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, - 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, - 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, - 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, - 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, - 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, - 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, - 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, - 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, - 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, - 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, - 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, - 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, - 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, - 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, - 0x74, 0x05, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gb01[0x685] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xFF, 0x12, 0x0B, 0x88, 0x10, 0x00, - 0x14, 0x00, 0x0B, 0x00, 0x13, 0x00, 0x47, 0x00, 0x45, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x46, 0x00, - 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x18, 0x00, 0x06, - 0x20, 0x10, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x4F, 0x13, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, - 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, - 0x80, 0x0A, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, - 0x23, 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x1F, 0x34, 0x1A, 0x01, - 0x07, 0x03, 0x79, 0x03, 0x08, 0x21, 0x00, 0xAF, 0x10, 0x08, 0x01, 0x03, 0x00, 0x50, 0x00, 0x40, - 0x01, 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1B, 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, - 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, - 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, - 0x04, 0x00, 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, - 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, - 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, - 0x0E, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, - 0x30, 0x02, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, - 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, - 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, - 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, - 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, - 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, - 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, - 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x07, 0x70, 0x03, - 0x04, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, - 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0x82, 0x05, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, - 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, - 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, - 0xC0, 0x8C, 0x09, 0x0D, 0xB3, 0x06, 0x06, 0x0B, 0x88, 0x0A, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x0B, - 0xDE, 0x03, 0x13, 0x07, 0x8E, 0x01, 0x51, 0x09, 0x00, 0x05, 0x00, 0x07, 0x02, 0x00, 0x0F, 0x18, - 0x00, 0x05, 0x31, 0x0A, 0x00, 0x0A, 0x96, 0x09, 0x11, 0x06, 0x3E, 0x00, 0x3F, 0x0B, 0x00, 0x0A, - 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, - 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, - 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, - 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, - 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xA4, 0x0C, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, - 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, - 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, - 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, - 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, - 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, - 0x01, 0x23, 0x00, 0x29, 0x00, 0x27, 0x00, 0x2D, 0x00, 0x22, 0x00, 0x27, 0x00, 0x23, 0x00, 0x2C, - 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, - 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x62, - 0x05, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x80, 0x17, 0x13, 0x02, 0x10, 0x06, 0x17, 0x0D, 0xCC, 0x10, - 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, - 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, - 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, - 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, - 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, - 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x11, 0x00, 0xF2, 0x02, 0x00, 0x0A, 0x00, 0x13, - 0x14, 0xAC, 0x00, 0x04, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, - 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, - 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, - 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH1y4gb01[0x679] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, - 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, - 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, - 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, - 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, - 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, - 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, - 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, - 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, - 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, - 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, - 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, - 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, - 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, - 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, - 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00, - 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, - 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, - 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x08, 0x74, 0x0A, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xC4, - 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, - 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, - 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, - 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, - 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, - 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, - 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, - 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, - 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, - 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, - 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, - 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, - 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, - 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, - 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, - 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, - 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12, - 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, - 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, - 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, - 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, - 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, - 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, - 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, - 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, - 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, - 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, - 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, - 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, - 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, - 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, - 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, - 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, - 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, - 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, - 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, - 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, - 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, - 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, - 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, - 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, 0x00, - 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, - 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, - 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, - 0x2C, 0x00, 0x07, 0x20, 0x80, 0x18, 0x3F, 0x01, 0x3F, 0x00, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, - 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, - 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, - 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD3, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, 0x88, 0x01, 0x13, 0x03, - 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, - 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, - 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, - 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, - 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, - 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, - 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, - 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, - 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, - 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, - 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, - 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, - 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, - 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, - 0x20, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, - 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, - 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, - 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, - 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, - 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, - 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, - 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, - 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, - 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, - 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, - 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, - 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x04, - 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x78, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, - 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, - 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, - 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, - 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, - 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, - 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, - 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, - 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, - 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, - 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, - 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, - 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, - 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, - 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, - 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, - 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, - 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, - 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, - 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, - 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, - 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, - 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, - 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, - 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, - 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, - 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x70, 0x00, 0x13, 0x10, - 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, - 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, - 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, - 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, - 0x00, 0x0E, 0x00, 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, - 0x00, 0x05, 0x20, 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, - 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, - 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, - 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, - 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, - 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, - 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, - 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, - 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, - 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, - 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, 0x04, - 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, - 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, - 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, - 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, - 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, - 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, - 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, - 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, - 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, - 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, - 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, - 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, - 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, - 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, - 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = { - 0xFF, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x56, 0x34, 0x5F, 0x56, 0x30, 0x2E, 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, - 0x00, 0x10, 0x71, 0xE0, 0x1C, 0x03, 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, - 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x39, 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, - 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, - 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, - 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, - 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, - 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, - 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, 0x08, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, - 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, - 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, - 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, - 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, - 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, - 0xFF, 0x12, 0x0B, 0x08, 0x10, 0x00, 0x14, 0x00, 0x0B, 0x00, 0x13, 0x00, 0x47, 0x00, 0x45, 0x00, - 0x4F, 0x00, 0x4D, 0x00, 0x46, 0x00, 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08, 0x00, 0x0C, 0x00, - 0x0C, 0x00, 0x0B, 0x18, 0x00, 0x06, 0x20, 0x10, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, - 0x00, 0x4F, 0x13, 0x00, 0x10, 0x00, 0x01, 0x00, 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, - 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, - 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, - 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, - 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, - 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, - 0x92, 0x02, 0x1F, 0x34, 0x1A, 0x01, 0x07, 0x03, 0x79, 0x03, 0x08, 0x21, 0x00, 0xAF, 0x10, 0x00, - 0x01, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00, 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, - 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, - 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x08, - 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, - 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, - 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, - 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, - 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, - 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, - 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, - 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, - 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, 0x03, - 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, 0x03, - 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x48, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x1B, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, - 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, - 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, - 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, 0x06, 0x00, 0x14, 0x00, - 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, - 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, - 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, - 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, - 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, - 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, - 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x07, 0x70, 0x03, 0x04, 0x98, 0x07, 0x90, - 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, 0x5D, 0x5D, 0x0E, - 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, 0x00, - 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x95, 0x01, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, - 0x07, 0x10, 0x10, 0x82, 0x05, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0x48, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB3, 0x06, - 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x0B, 0xDE, 0x03, 0x13, 0x07, 0x8E, 0x01, - 0x51, 0x09, 0x00, 0x05, 0x00, 0x07, 0x02, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x31, 0x0A, 0x00, 0x0A, - 0x96, 0x09, 0x11, 0x06, 0x3E, 0x00, 0x3F, 0x0B, 0x00, 0x0A, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, - 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, - 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, - 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, - 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, - 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, - 0x33, 0xA4, 0x0C, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, - 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, - 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, - 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, - 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, - 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, - 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0x7C, 0x0F, 0xAE, 0x1B, 0x29, 0x01, - 0x00, 0xF4, 0x01, 0x23, 0x00, 0x29, 0x00, 0x27, 0x00, 0x2D, 0x00, 0x22, 0x00, 0x27, 0x00, 0x23, - 0x00, 0x2C, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, - 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, - 0x06, 0x62, 0x05, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, - 0x82, 0x05, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, - 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, - 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, - 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, - 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, - 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x11, 0x00, 0xF2, 0x02, 0x00, 0x0A, - 0x00, 0x13, 0x14, 0xAC, 0x00, 0x04, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, - 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, - 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, - 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, - 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, - 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, - 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, - 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, - 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, - 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, - 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, - 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, - 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, - 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, - 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, - 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, - 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, - 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, - 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, - 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, - 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, - 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, - 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, - 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, - 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, - 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[0x681] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, - 0x08, 0xFC, 0x05, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, - 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, - 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, - 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, - 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, - 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, - 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, - 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, - 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, - 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, - 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, - 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, - 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, - 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, - 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, - 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, - 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, - 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, - 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, - 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, - 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, - 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, - 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, - 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x03, - 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, 0x0E, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, 0x8C, 0x09, 0xA0, 0xD0, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, - 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, - 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, - 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, - 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, - 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, - 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, - 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, - 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, - 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, - 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, - 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, - 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, - 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, - 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, - 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, - 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, - 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, - 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, - 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, - 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, - 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, - 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, - 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, - 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, - 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, - 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, - 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, - 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, - 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, - 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, - 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, - 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, - 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, - 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, - 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, - 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x10, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x13, 0x29, 0x01, 0x00, 0x13, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0xD8, 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, - 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, - 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, - 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, - 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, - 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, - 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, - 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, - 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, - 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, - 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, - 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, - 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, - 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, - 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x35, 0x50, 0x50, 0xA0, 0x8C, 0x09, 0x5F, 0x8C, 0x30, - 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, - 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, - 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, - 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, - 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, - 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, - 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, - 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, - 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, - 0xB6, 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, - 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, - 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0x50, 0x1F, 0x0B, 0x04, 0x00, 0x11, - 0x0F, 0xCC, 0x00, 0x20, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, - 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, - 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, - 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, - 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, - 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, - 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, - 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, - 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, - 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, - 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, - 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[0x680] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, - 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, - 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, - 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, - 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, - 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, - 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, - 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, - 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, - 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, - 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, - 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, - 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, - 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, 0x17, - 0x01, 0x04, 0x00, 0x17, 0x02, 0x0C, 0x06, 0x1B, 0x01, 0xFC, 0x05, 0x11, 0x07, 0x14, 0x00, 0xE3, - 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, - 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, - 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, - 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, - 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, - 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, - 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, - 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, - 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, - 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, - 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, - 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, - 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, - 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, - 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, - 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, - 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, - 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, - 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, - 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x50, - 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, - 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, 0x00, - 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, - 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, - 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, - 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, - 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, - 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, - 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, - 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, - 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, - 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, - 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, - 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, - 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, - 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0xA8, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, - 0x13, 0x02, 0x74, 0x05, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, - 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, - 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, - 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, - 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, - 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, - 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, - 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, - 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, - 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, - 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin" }; diff --git a/fusee/program/source/sdram/fusee_sdram_params.inc b/fusee/program/source/sdram/fusee_sdram_params.inc index 133e42b9f..a89dcd2ca 100644 --- a/fusee/program/source/sdram/fusee_sdram_params.inc +++ b/fusee/program/source/sdram/fusee_sdram_params.inc @@ -14,68 +14,8 @@ * along with this program. If not, see . */ -constexpr inline const u8 SdramParamsErista0_1[0x3CA] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03, 0x5F, - 0x01, 0x1F, 0x80, 0x68, 0x07, 0xFF, 0xFF, 0xFF, 0x71, 0x1F, 0x02, 0x68, 0x07, 0xB7, 0x1F, 0x05, - 0x68, 0x07, 0xFF, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista0_1[0x3CB] = { + #embed "../../sdram_params/lz/sdram_params_erista_0_1.lz4" }; constexpr inline const u8 * const SdramParamsErista0 = SdramParamsErista0_1; @@ -84,68 +24,8 @@ constexpr inline const size_t SdramParamsSizeErista0 = sizeof(SdramParamsErista0 constexpr inline const u8 * const SdramParamsErista1 = SdramParamsErista0_1; constexpr inline const size_t SdramParamsSizeErista1 = sizeof(SdramParamsErista0_1); -constexpr inline const u8 SdramParamsErista2_3[0x3C6] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xFF, 0x9E, 0x1F, 0x12, 0x68, 0x07, 0x18, 0x1F, - 0x03, 0x68, 0x07, 0xFF, 0xFF, 0xAE, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0xFF, 0xFF, 0xAE, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista2_3[0x3C7] = { + #embed "../../sdram_params/lz/sdram_params_erista_2_3.lz4" }; constexpr inline const u8 * const SdramParamsErista2 = SdramParamsErista2_3; @@ -154,73 +34,8 @@ constexpr inline const size_t SdramParamsSizeErista2 = sizeof(SdramParamsErista2 constexpr inline const u8 * const SdramParamsErista3 = SdramParamsErista2_3; constexpr inline const size_t SdramParamsSizeErista3 = sizeof(SdramParamsErista2_3); -constexpr inline const u8 SdramParamsErista4_5[0x417] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x0C, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03, 0x5F, - 0x01, 0x1F, 0x80, 0x68, 0x07, 0x29, 0x1F, 0x12, 0x68, 0x07, 0x18, 0x1F, 0x03, 0x68, 0x07, 0xFF, - 0x45, 0x11, 0x15, 0xF6, 0x06, 0x1F, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F, 0x00, - 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0E, 0x18, 0x00, - 0x0F, 0x68, 0x07, 0x13, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3F, 0x16, 0x00, 0x15, 0x68, - 0x07, 0xD4, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0x3E, 0x1F, 0x02, 0x68, 0x07, 0x65, 0x11, - 0x07, 0x04, 0x00, 0x0D, 0x68, 0x07, 0x1F, 0x10, 0x68, 0x07, 0x27, 0x1F, 0x05, 0x68, 0x07, 0xFF, - 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista4_5[0x418] = { + #embed "../../sdram_params/lz/sdram_params_erista_4_5.lz4" }; constexpr inline const u8 * const SdramParamsErista4 = SdramParamsErista4_5; @@ -229,67 +44,8 @@ constexpr inline const size_t SdramParamsSizeErista4 = sizeof(SdramParamsErista4 constexpr inline const u8 * const SdramParamsErista5 = SdramParamsErista4_5; constexpr inline const size_t SdramParamsSizeErista5 = sizeof(SdramParamsErista4_5); -constexpr inline const u8 SdramParamsErista6_7[0x3BC] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x13, 0x05, 0x30, 0x00, - 0x00, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x29, 0x00, 0xF1, - 0x29, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, - 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, - 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, - 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, - 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, - 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, - 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, - 0x67, 0x02, 0x70, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, - 0x11, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, - 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, - 0x10, 0x00, 0xA2, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, - 0x08, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, - 0x11, 0x01, 0x00, 0x10, 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, - 0x7F, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F, - 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0F, 0x18, - 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3B, 0x16, - 0x00, 0x15, 0x78, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, - 0x00, 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x0C, 0x02, 0x54, 0xAB, 0x00, 0x0A, - 0x04, 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, - 0x03, 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, - 0x38, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, - 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, - 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, - 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, - 0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, - 0x94, 0x04, 0x11, 0x37, 0x16, 0x03, 0x30, 0x00, 0x00, 0x10, 0x05, 0x00, 0x51, 0x30, 0x00, 0x00, - 0x11, 0x01, 0xB9, 0x02, 0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, - 0x12, 0x00, 0x00, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, - 0x67, 0x76, 0x2C, 0x01, 0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, - 0xDC, 0xDC, 0x0A, 0x01, 0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, - 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, - 0x10, 0x58, 0x01, 0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, - 0x02, 0x0C, 0x74, 0x01, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x11, - 0x07, 0x10, 0x00, 0xC4, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, - 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, - 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, - 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, - 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, - 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, - 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, - 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2E, 0xEC, 0x00, 0x3C, 0x01, 0x0F, 0x01, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista6_7[0x3BD] = { + #embed "../../sdram_params/lz/sdram_params_erista_6_7.lz4" }; constexpr inline const u8 * const SdramParamsErista6 = SdramParamsErista6_7; @@ -298,70 +54,8 @@ constexpr inline const size_t SdramParamsSizeErista6 = sizeof(SdramParamsErista6 constexpr inline const u8 * const SdramParamsErista7 = SdramParamsErista6_7; constexpr inline const size_t SdramParamsSizeErista7 = sizeof(SdramParamsErista6_7); -constexpr inline const u8 SdramParamsMariko0_1[0x3EC] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x82, - 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x0E, 0x00, 0x11, 0x88, 0x04, 0x00, 0x26, 0x20, - 0x12, 0x0C, 0x00, 0x02, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, 0xBC, 0xBC, 0xC5, 0xB3, 0x3C, 0x9E, - 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, - 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, - 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, - 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, - 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, - 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, - 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, - 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, - 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, - 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, - 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, - 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, - 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, - 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, - 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, - 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, - 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, - 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x2C, - 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, - 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, - 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, - 0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, - 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, - 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x22, 0x00, 0x0E, 0x00, 0x10, 0x00, 0x1B, - 0x18, 0x00, 0x06, 0xF3, 0x02, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47, 0x00, 0x49, - 0x00, 0x47, 0x00, 0x46, 0x00, 0x16, 0xE6, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, - 0x0C, 0x11, 0x22, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x1B, 0x00, 0x22, 0x94, - 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, - 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, - 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, - 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, - 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, - 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, - 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, - 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, - 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, - 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, - 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, - 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, - 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, - 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, - 0x00, 0x10, 0xA4, 0x01, 0xEF, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0xC0, 0x01, 0x00, 0x04, 0x08, 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, - 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, - 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, - 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, 0x68, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, - 0x0B, 0x05, 0x2F, 0xF0, 0xFF, 0xF4, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, - 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, - 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, - 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, - 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, - 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0x9C, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, - 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x0F, 0x38, - 0x08, 0x0D, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, - 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko0_1[0x3EE] = { + #embed "../../sdram_params/lz/sdram_params_mariko_0_1.lz4" }; constexpr inline const u8 * const SdramParamsMariko0 = SdramParamsMariko0_1; @@ -370,76 +64,8 @@ constexpr inline const size_t SdramParamsSizeMariko0 = sizeof(SdramParamsMariko0 constexpr inline const u8 * const SdramParamsMariko1 = SdramParamsMariko0_1; constexpr inline const size_t SdramParamsSizeMariko1 = sizeof(SdramParamsMariko0_1); -constexpr inline const u8 SdramParamsMariko2_3[0x447] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x61, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x30, 0x01, 0x13, - 0x02, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, - 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, - 0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, - 0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, - 0x00, 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, - 0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, - 0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, - 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, - 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, - 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, - 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, - 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, - 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, - 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x08, 0x00, 0x00, - 0x0B, 0x08, 0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, - 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, - 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, - 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08, - 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, - 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x00, 0x64, 0x01, 0xB3, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x35, 0x01, 0x00, 0x13, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, - 0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, - 0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, - 0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x10, 0x02, 0x00, 0x0C, 0x11, 0x16, - 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, - 0x54, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x18, 0x00, 0x63, - 0x80, 0x01, 0x00, 0x00, 0x40, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, - 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x05, 0x78, 0x03, 0x78, 0x01, 0x22, - 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x88, 0x03, 0x04, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x80, 0x00, - 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, - 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, - 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, - 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, - 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, - 0x00, 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, - 0x04, 0x14, 0x40, 0x8B, 0x02, 0x1D, 0x00, 0x9D, 0x02, 0x01, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, - 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, 0x10, 0x04, - 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4C, 0x1C, 0x1C, 0x1C, 0x1C, 0xF0, 0x01, 0x31, - 0x02, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, - 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x20, 0x20, 0x00, 0xB1, 0x08, 0x4C, 0x00, 0x00, - 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x04, 0x02, 0x0D, 0xC0, 0x01, 0x04, 0x08, 0x00, 0x17, - 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x11, 0x07, 0x10, 0x00, 0xE2, 0x02, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x04, 0x84, 0x03, 0x35, 0x00, 0x00, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xC3, - 0x2F, 0x00, 0x00, 0x38, 0x08, 0x0B, 0x2F, 0xC5, 0xB3, 0x38, 0x08, 0x29, 0x1F, 0x00, 0x38, 0x08, - 0x84, 0x13, 0x05, 0x1C, 0x00, 0x08, 0x78, 0x05, 0x1F, 0x0D, 0x38, 0x08, 0xC7, 0x93, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x38, 0x08, 0xF2, 0x0A, 0x88, 0x00, 0x00, 0x0B, 0x88, - 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, - 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x43, 0x1B, 0x02, 0x38, 0x08, 0x04, 0x30, - 0x08, 0x0F, 0x38, 0x08, 0x91, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x0F, 0x38, 0x08, 0x24, 0x14, 0x80, - 0x38, 0x08, 0x04, 0x20, 0x00, 0x0F, 0x38, 0x08, 0xFF, 0x1E, 0x7F, 0x80, 0x00, 0x40, 0x00, 0x04, - 0x10, 0x80, 0x38, 0x08, 0x82, 0x1F, 0x00, 0x38, 0x08, 0x09, 0x1F, 0x10, 0x38, 0x08, 0x1F, 0x1F, - 0x01, 0x38, 0x08, 0x00, 0x1F, 0x00, 0x38, 0x08, 0x36, 0x0E, 0xFC, 0x06, 0x0F, 0x38, 0x08, 0xFF, - 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko2_3[0x449] = { + #embed "../../sdram_params/lz/sdram_params_mariko_2_3.lz4" }; constexpr inline const u8 * const SdramParamsMariko2 = SdramParamsMariko2_3; @@ -448,71 +74,8 @@ constexpr inline const size_t SdramParamsSizeMariko2 = sizeof(SdramParamsMariko2 constexpr inline const u8 * const SdramParamsMariko3 = SdramParamsMariko2_3; constexpr inline const size_t SdramParamsSizeMariko3 = sizeof(SdramParamsMariko2_3); -constexpr inline const u8 SdramParamsMariko4_5[0x3F5] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, - 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, - 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, - 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, - 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, - 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, - 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, - 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, - 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, - 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01, - 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, - 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, - 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x14, - 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A, - 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01, - 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, - 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01, - 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31, - 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45, - 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01, - 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C, - 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01, - 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, - 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, - 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, - 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, - 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, - 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, - 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, - 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, - 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, - 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, - 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, - 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, - 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, - 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, - 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, - 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, - 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, - 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, - 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, - 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, - 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, - 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, - 0xFF, 0xFF, 0xFF, 0x40, 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0x41, 0x3E, 0x18, 0x00, 0x0F, - 0x38, 0x08, 0x07, 0x18, 0x00, 0x93, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x20, - 0x08, 0x11, 0x0D, 0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x78, 0x02, 0x00, 0x0C, 0x11, - 0x18, 0x5A, 0x00, 0x15, 0x0F, 0x38, 0x08, 0x1F, 0x18, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x50, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko4_5[0x3F7] = { + #embed "../../sdram_params/lz/sdram_params_mariko_4_5.lz4" }; constexpr inline const u8 * const SdramParamsMariko4 = SdramParamsMariko4_5; @@ -521,74 +84,8 @@ constexpr inline const size_t SdramParamsSizeMariko4 = sizeof(SdramParamsMariko4 constexpr inline const u8 * const SdramParamsMariko5 = SdramParamsMariko4_5; constexpr inline const size_t SdramParamsSizeMariko5 = sizeof(SdramParamsMariko4_5); -constexpr inline const u8 SdramParamsMariko6_7[0x425] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, 0x22, 0x20, - 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, - 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, - 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, - 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, - 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, - 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, - 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, - 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, - 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, - 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, - 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, - 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, - 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, - 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, - 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, - 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, - 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, - 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, - 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, 0x00, - 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, 0x00, - 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, - 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x05, 0x1F, 0x08, 0x38, 0x08, 0x5B, 0x93, 0x08, 0x00, 0x00, - 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x5D, - 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, - 0x14, 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1F, 0x00, 0x38, - 0x08, 0xFF, 0x00, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06, 0x1F, 0x40, 0x38, 0x08, 0xFF, 0x22, 0x04, - 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38, 0x08, 0x09, 0x1F, 0x20, 0x38, 0x08, 0x0F, - 0x1B, 0x01, 0x38, 0x08, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x8C, 0x50, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko6_7[0x427] = { + #embed "../../sdram_params/lz/sdram_params_mariko_6_7.lz4" }; constexpr inline const u8 * const SdramParamsMariko6 = SdramParamsMariko6_7; @@ -597,74 +94,8 @@ constexpr inline const size_t SdramParamsSizeMariko6 = sizeof(SdramParamsMariko6 constexpr inline const u8 * const SdramParamsMariko7 = SdramParamsMariko6_7; constexpr inline const size_t SdramParamsSizeMariko7 = sizeof(SdramParamsMariko6_7); -constexpr inline const u8 SdramParamsMariko8_9[0x426] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, - 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, - 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, - 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, - 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, - 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, - 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, - 0x02, 0x31, 0x7F, 0x18, 0x00, 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x48, - 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, - 0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x18, 0x5A, 0x00, - 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x18, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, - 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, - 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, - 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, - 0xFF, 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, - 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, - 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, - 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, - 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, - 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, - 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, - 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, - 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, - 0x4D, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, - 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, - 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08, 0xC0, 0x01, - 0x17, 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, - 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, - 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, - 0x15, 0xF0, 0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B, 0x80, 0x2A, - 0x02, 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, - 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, - 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, - 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, - 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, - 0x0F, 0x38, 0x08, 0xFF, 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x74, 0x93, 0x08, 0x00, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x5D, 0x5D, - 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, - 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1B, 0x00, 0x38, 0x08, - 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0xE8, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06, 0x1F, 0x40, - 0x38, 0x08, 0xFF, 0x22, 0x04, 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38, 0x08, 0x09, - 0x1F, 0x20, 0x38, 0x08, 0x1F, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x8C, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko8_9[0x428] = { + #embed "../../sdram_params/lz/sdram_params_mariko_8_9.lz4" }; constexpr inline const u8 * const SdramParamsMariko8 = SdramParamsMariko8_9; @@ -673,68 +104,8 @@ constexpr inline const size_t SdramParamsSizeMariko8 = sizeof(SdramParamsMariko8 constexpr inline const u8 * const SdramParamsMariko9 = SdramParamsMariko8_9; constexpr inline const size_t SdramParamsSizeMariko9 = sizeof(SdramParamsMariko8_9); -constexpr inline const u8 SdramParamsMariko10_11[0x3D0] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, 0x22, 0x20, - 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, - 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, - 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, - 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, - 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, - 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, - 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, - 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, - 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, - 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, - 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, - 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, - 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, - 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, - 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, - 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, - 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, - 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, - 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, 0x00, - 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, 0x00, - 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, - 0xFF, 0x3B, 0x1F, 0x08, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x1F, 0x01, 0x38, 0x08, 0x51, - 0x5F, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x38, 0x08, 0xFF, 0x47, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko10_11[0x3D2] = { + #embed "../../sdram_params/lz/sdram_params_mariko_10_11.lz4" }; constexpr inline const u8 * const SdramParamsMariko10 = SdramParamsMariko10_11; @@ -743,67 +114,8 @@ constexpr inline const size_t SdramParamsSizeMariko10 = sizeof(SdramParamsMariko constexpr inline const u8 * const SdramParamsMariko11 = SdramParamsMariko10_11; constexpr inline const size_t SdramParamsSizeMariko11 = sizeof(SdramParamsMariko10_11); -constexpr inline const u8 SdramParamsMariko12_13[0x3C0] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, - 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, - 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, - 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, - 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, - 0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, - 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, - 0x00, 0x0D, 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, - 0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, - 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, - 0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, - 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, - 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, - 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, - 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, - 0x08, 0x00, 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, - 0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, - 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, - 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, - 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, - 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, - 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, - 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, - 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, - 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, - 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08, 0xC0, 0x01, 0x17, - 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, - 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, - 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, - 0xF0, 0x24, 0x04, 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, - 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, - 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, - 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, - 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, - 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0E, 0x3C, 0x01, 0x0F, 0x01, - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2C, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko12_13[0x3C2] = { + #embed "../../sdram_params/lz/sdram_params_mariko_12_13.lz4" }; constexpr inline const u8 * const SdramParamsMariko12 = SdramParamsMariko12_13; diff --git a/fusee/program/update_mtc_tables.py b/fusee/program/update_mtc_tables.py index 7a7e0edd1..a6f73b07c 100644 --- a/fusee/program/update_mtc_tables.py +++ b/fusee/program/update_mtc_tables.py @@ -57,6 +57,22 @@ def main(argc, argv): except: pass write_file(os.path.join('mtc_tables/lz/%s' % board, '%d.lz4' % i), compressed) + try: + os.makedirs('mtc_tables/combined/%s' % board) + except: + pass + data_1600 = params[soc][board][-1] + data_800 = params[soc][board][-4] if soc == 'erista' else '' + data_204 = params[soc][board][0] if soc == 'mariko' else params[soc][board][3] + assert up('; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 95c316d68..837ad7351 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,8 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_20_0_0, + TargetFirmware_19_0_0, TargetFirmware_17_0_0, TargetFirmware_16_0_0, TargetFirmware_15_0_0, diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 8b9a6953c..b653da7bd 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -110,47 +110,47 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsMappedEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); virt_addr += L1BlockSize; - if (l1_entry->IsBlock() && block_size == L1BlockSize) { + if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* 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; + if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { + const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l2_entry->IsBlock() && block_size == advance_size) { + if (l2_entry->IsMappedBlock() && block_size == advance_size) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* 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()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); - const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l3_entry->IsBlock() && block_size == advance_size) { + if (l3_entry->IsMappedBlock() && block_size == advance_size) { count++; } } @@ -164,10 +164,10 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsMappedEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); - if (l1_entry->IsBlock() && block_size == L1BlockSize) { + if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) { if ((count++) == index) { return virt_addr; } @@ -177,16 +177,16 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* 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; + if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { + const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l2_entry->IsBlock() && block_size == advance_size) { + if (l2_entry->IsMappedBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -196,18 +196,18 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* 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()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); - const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l3_entry->IsBlock() && block_size == advance_size) { + if (l3_entry->IsMappedBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -220,29 +220,29 @@ namespace ams::kern::arch::arm64::init { PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize); return l1_entry; } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { 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()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* 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()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); const size_t real_size = (l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size); @@ -340,7 +340,7 @@ namespace ams::kern::arch::arm64::init { } /* If we don't already have an L2 table, we need to make a new one. */ - if (!l1_entry->IsTable()) { + if (!l1_entry->IsMappedTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -371,7 +371,7 @@ namespace ams::kern::arch::arm64::init { } /* If we don't already have an L3 table, we need to make a new one. */ - if (!l2_entry->IsTable()) { + if (!l2_entry->IsMappedTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -416,12 +416,12 @@ namespace ams::kern::arch::arm64::init { for (size_t l1_index = 0; l1_index < m_num_entries[0]; l1_index++) { /* Get L1 entry. */ L1PageTableEntry * const l1_entry = l1_table + l1_index; - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { /* Unmap the L1 entry, if we should. */ if (ShouldUnmap(l1_entry)) { *static_cast(l1_entry) = InvalidPageTableEntry; } - } else if (l1_entry->IsTable()) { + } else if (l1_entry->IsMappedTable()) { /* Get the L2 table. */ L2PageTableEntry * const l2_table = reinterpret_cast(GetInteger(l1_entry->GetTable()) + phys_to_virt_offset); @@ -430,7 +430,7 @@ namespace ams::kern::arch::arm64::init { for (size_t l2_index = 0; l2_index < MaxPageTableEntries; ++l2_index) { /* Get L2 entry. */ L2PageTableEntry * const l2_entry = l2_table + l2_index; - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { const size_t num_to_clear = (l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize) / L2BlockSize; if (ShouldUnmap(l2_entry)) { @@ -442,7 +442,7 @@ namespace ams::kern::arch::arm64::init { } l2_index = l2_index + num_to_clear - 1; - } else if (l2_entry->IsTable()) { + } else if (l2_entry->IsMappedTable()) { /* Get the L3 table. */ L3PageTableEntry * const l3_table = reinterpret_cast(GetInteger(l2_entry->GetTable()) + phys_to_virt_offset); @@ -450,7 +450,7 @@ namespace ams::kern::arch::arm64::init { size_t remaining_l3_entries = 0; for (size_t l3_index = 0; l3_index < MaxPageTableEntries; ++l3_index) { /* Get L3 entry. */ - if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsBlock()) { + if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsMappedBlock()) { const size_t num_to_clear = (l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize) / L3BlockSize; if (ShouldUnmap(l3_entry)) { @@ -498,25 +498,25 @@ namespace ams::kern::arch::arm64::init { /* Get the L1 entry. */ const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Get the L2 entry. */ const L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { return l2_entry->GetBlock() + (GetInteger(virt_addr) & (L2BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* Get the L3 entry. */ const L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); return l3_entry->GetBlock() + (GetInteger(virt_addr) & (L3BlockSize - 1)); } @@ -561,26 +561,26 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped, update. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { UpdateExtents(l1_entry->GetBlock(), L1BlockSize); continue; } /* Not a block, so we must have a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { UpdateExtents(l2_entry->GetBlock(), l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize); continue; } /* Not a block, so we must have a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* We must have a mapped l3 entry to inspect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); UpdateExtents(l3_entry->GetBlock(), l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize); } @@ -602,11 +602,11 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped, the address isn't free. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { return false; } - if (!l1_entry->IsTable()) { + if (!l1_entry->IsMappedTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L1BlockSize, L1BlockSize); continue; @@ -615,11 +615,11 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { return false; } - if (!l2_entry->IsTable()) { + if (!l2_entry->IsMappedTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L2BlockSize, L2BlockSize); continue; @@ -628,7 +628,7 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - if (l3_entry->IsBlock()) { + if (l3_entry->IsMappedBlock()) { return false; } @@ -648,7 +648,7 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* Check if an L1 block is present. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { /* Ensure that we are allowed to have an L1 block here. */ const KPhysicalAddress block = l1_entry->GetBlock(); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); @@ -669,10 +669,10 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { const KPhysicalAddress block = l2_entry->GetBlock(); if (l2_entry->IsContiguous()) { @@ -720,11 +720,11 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* We must have a mapped l3 entry to reprotect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); const KPhysicalAddress block = l3_entry->GetBlock(); if (l3_entry->IsContiguous()) { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 14aba9913..7bc1a96f1 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -93,9 +93,13 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(alignment < L1BlockSize); return KPageTable::GetBlockSize(static_cast(KPageTable::GetBlockType(alignment) + 1)); } + public: + /* TODO: How should this size be determined. Does the KProcess slab count need to go in a header as a define? */ + static constexpr size_t NumTtbr0Entries = 81; + private: + static constinit inline const volatile u64 s_ttbr0_entries[NumTtbr0Entries] = {}; private: KPageTableManager *m_manager; - u64 m_ttbr; u8 m_asid; protected: Result OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll); @@ -105,6 +109,9 @@ namespace ams::kern::arch::arm64 { KPageTableManager &GetPageTableManager() const { return *m_manager; } private: constexpr PageTableEntry GetEntryTemplate(const KPageProperties properties) const { + /* Check that the property is not kernel execute. */ + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_KernelExecute) == 0); + /* Set basic attributes. */ PageTableEntry entry{PageTableEntry::ExtensionFlag_Valid}; entry.SetPrivilegedExecuteNever(true); @@ -118,22 +125,24 @@ namespace ams::kern::arch::arm64 { /* Set page attribute. */ if (properties.io) { MESOSPHERE_ABORT_UNLESS(!properties.uncached); - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); entry.SetPageAttribute(PageTableEntry::PageAttribute_Device_nGnRnE) .SetUserExecuteNever(true); } else if (properties.uncached) { - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); - entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable); + entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable) + .SetUserExecuteNever(true); } else { entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemory); - } - /* Set user execute never bit. */ - if (properties.perm != KMemoryPermission_UserReadExecute) { - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); - entry.SetUserExecuteNever(true); + if ((properties.perm & KMemoryPermission_UserExecute) != 0) { + /* Check that the permission is either r--/--x or r--/r-x. */ + MESOSPHERE_ABORT_UNLESS((properties.perm & ~ams::svc::MemoryPermission_Read) == (KMemoryPermission_KernelRead | KMemoryPermission_UserExecute)); + } else { + entry.SetUserExecuteNever(true); + } } /* Set AP[1] based on perm. */ @@ -168,53 +177,47 @@ namespace ams::kern::arch::arm64 { return entry; } public: - constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ } + constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_asid() { /* ... */ } explicit KPageTable() { /* ... */ } static NOINLINE void Initialize(s32 core_id); - ALWAYS_INLINE void Activate(u32 proc_id) { - cpu::SwitchProcess(m_ttbr, proc_id); + static const volatile u64 &GetTtbr0Entry(size_t index) { return s_ttbr0_entries[index]; } + + static ALWAYS_INLINE u64 GetKernelTtbr0() { + return s_ttbr0_entries[0]; + } + + static ALWAYS_INLINE void ActivateKernel() { + /* Activate, using asid 0 and process id = 0xFFFFFFFF */ + cpu::SwitchProcess(GetKernelTtbr0(), 0xFFFFFFFF); + } + + static ALWAYS_INLINE void ActivateProcess(size_t proc_idx, u32 proc_id) { + cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id); } NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); Result Finalize(); - private: - Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); - Result MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); - Result MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); + static void NoteUpdatedCallback(const void *pt) { + /* Note the update. */ + static_cast(pt)->NoteUpdated(); + } + private: Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll); - Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { - switch (page_size) { - case L1BlockSize: - R_RETURN(this->MapL1Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - case L2ContiguousBlockSize: - entry_template.SetContiguous(true); - [[fallthrough]]; -#ifdef ATMOSPHERE_BOARD_NINTENDO_NX - case L2TegraSmmuBlockSize: -#endif - case L2BlockSize: - R_RETURN(this->MapL2Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - case L3ContiguousBlockSize: - entry_template.SetContiguous(true); - [[fallthrough]]; - case L3BlockSize: - R_RETURN(this->MapL3Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } + Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll); Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll); - bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); + bool MergePages(TraversalContext *context, PageLinkedList *page_list); + void MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list); - ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); - Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); + Result SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); + Result SeparatePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool reuse_ll); Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll); @@ -224,7 +227,6 @@ namespace ams::kern::arch::arm64 { static ALWAYS_INLINE void ClearPageTable(KVirtualAddress table) { cpu::ClearPageToZero(GetVoidPointer(table)); - cpu::DataSynchronizationBarrierInnerShareable(); } ALWAYS_INLINE void OnTableUpdated() const { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index 93925e3fa..ed32262f9 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -20,18 +20,22 @@ namespace ams::kern::arch::arm64 { + constexpr size_t BlocksPerContiguousBlock = 0x10; + constexpr size_t BlocksPerTable = PageSize / sizeof(u64); + constexpr size_t L1BlockSize = 1_GB; - constexpr size_t L1ContiguousBlockSize = 0x10 * L1BlockSize; + constexpr size_t L1ContiguousBlockSize = BlocksPerContiguousBlock * L1BlockSize; constexpr size_t L2BlockSize = 2_MB; - constexpr size_t L2ContiguousBlockSize = 0x10 * L2BlockSize; + constexpr size_t L2ContiguousBlockSize = BlocksPerContiguousBlock * L2BlockSize; constexpr size_t L3BlockSize = PageSize; - constexpr size_t L3ContiguousBlockSize = 0x10 * L3BlockSize; + constexpr size_t L3ContiguousBlockSize = BlocksPerContiguousBlock * L3BlockSize; class PageTableEntry { public: struct InvalidTag{}; struct TableTag{}; struct BlockTag{}; + struct SeparateContiguousTag{}; enum Permission : u64 { Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)), @@ -118,7 +122,26 @@ namespace ams::kern::arch::arm64 { /* Construct a new attribute. */ constexpr explicit ALWAYS_INLINE PageTableEntry(Permission perm, PageAttribute p_a, Shareable share, MappingFlag m) - : m_attributes(static_cast(perm) | static_cast(AccessFlag_Accessed) | static_cast(p_a) | static_cast(share) | static_cast(ExtensionFlag_Valid) | static_cast(m)) + : m_attributes(static_cast(perm) | static_cast(AccessFlag_Accessed) | static_cast(p_a) | static_cast(share) | static_cast(m)) + { + /* ... */ + } + + /* Construct a table. */ + constexpr explicit ALWAYS_INLINE PageTableEntry(TableTag, KPhysicalAddress phys_addr, bool is_kernel, bool pxn, size_t ref_count) + : PageTableEntry(((is_kernel ? 0x3ul : 0) << 60) | (static_cast(pxn) << 59) | GetInteger(phys_addr) | (ref_count << 2) | 0x3) + { + /* ... */ + } + + /* Construct a block. */ + constexpr explicit ALWAYS_INLINE PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig, bool page) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | (page ? ExtensionFlag_TestTableMask : ExtensionFlag_Valid)) + { + /* ... */ + } + constexpr explicit ALWAYS_INLINE PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, SeparateContiguousTag) + : PageTableEntry(attr, GetInteger(phys_addr)) { /* ... */ } @@ -165,14 +188,24 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE Shareable GetShareable() const { return static_cast(this->SelectBits(8, 2)); } constexpr ALWAYS_INLINE PageAttribute GetPageAttribute() const { return static_cast(this->SelectBits(2, 3)); } constexpr ALWAYS_INLINE int GetAccessFlagInteger() const { return static_cast(this->GetBits(10, 1)); } - constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast(this->GetBits(8, 2)); } + constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast(this->GetBits(8, 2)); } constexpr ALWAYS_INLINE int GetPageAttributeInteger() const { return static_cast(this->GetBits(2, 3)); } 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 u64 GetTestTableMask() const { return (m_attributes & ExtensionFlag_TestTableMask); } + constexpr ALWAYS_INLINE bool IsBlock() const { return (m_attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_Valid; } + constexpr ALWAYS_INLINE bool IsPage() const { return (m_attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_TestTableMask; } constexpr ALWAYS_INLINE bool IsTable() const { return (m_attributes & ExtensionFlag_TestTableMask) == 2; } constexpr ALWAYS_INLINE bool IsEmpty() const { return (m_attributes & ExtensionFlag_TestTableMask) == 0; } + + constexpr ALWAYS_INLINE KPhysicalAddress GetTable() const { return this->SelectBits(12, 36); } + + constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 1; } + constexpr ALWAYS_INLINE bool IsMappedTable() const { return this->GetBits(0, 2) == 3; } + constexpr ALWAYS_INLINE bool IsMappedEmpty() const { return this->GetBits(0, 2) == 0; } constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; } constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; } @@ -186,8 +219,16 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; } + constexpr ALWAYS_INLINE size_t GetTableReferenceCount() const { return this->GetBits(2, 10); } + constexpr ALWAYS_INLINE decltype(auto) SetTableReferenceCount(size_t num) { this->SetBits(2, 10, num); return *this; } + + constexpr ALWAYS_INLINE decltype(auto) OpenTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() + num <= BlocksPerTable + 1); return this->SetTableReferenceCount(this->GetTableReferenceCount() + num); } + constexpr ALWAYS_INLINE decltype(auto) CloseTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() >= num); return this->SetTableReferenceCount(this->GetTableReferenceCount() - num); } + + constexpr ALWAYS_INLINE decltype(auto) SetValid() { MESOSPHERE_ASSERT((m_attributes & ExtensionFlag_Valid) == 0); m_attributes |= ExtensionFlag_Valid; return *this; } + constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const { - constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); return m_attributes & BaseMask; } @@ -196,10 +237,45 @@ namespace ams::kern::arch::arm64 { return (m_attributes & BaseMaskForMerge) == attr; } - constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const { + static constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateContiguousMask(size_t idx) { + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + if (idx == 0) { + return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerContiguousBlock - 1) { + return BaseMask; + } else { + return BaseMask | ExtensionFlag_DisableMergeTail; + } + } + + constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateContiguous(size_t idx) const { + return m_attributes & GetEntryTemplateForSeparateContiguousMask(idx); + } + + static constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateMask(size_t idx) { + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + if (idx == 0) { + return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerContiguousBlock) { + return BaseMask | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerTable - 1) { + return BaseMask; + } else { + return BaseMask | ExtensionFlag_DisableMergeTail; + } + } + + constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparate(size_t idx) const { + return m_attributes & GetEntryTemplateForSeparateMask(idx); + } + + constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafe() const { return m_attributes; } + constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const { + return m_attributes; + } protected: constexpr ALWAYS_INLINE u64 GetRawAttributes() const { return m_attributes; @@ -229,7 +305,7 @@ namespace ams::kern::arch::arm64 { } constexpr explicit ALWAYS_INLINE L1PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x1) { /* ... */ } @@ -291,7 +367,7 @@ namespace ams::kern::arch::arm64 { } constexpr explicit ALWAYS_INLINE L2PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x1) { /* ... */ } @@ -356,12 +432,13 @@ namespace ams::kern::arch::arm64 { constexpr explicit ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ } constexpr explicit ALWAYS_INLINE L3PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | static_cast(ExtensionFlag_TestTableMask)) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x3) { /* ... */ } constexpr ALWAYS_INLINE bool IsBlock() const { return (GetRawAttributes() & ExtensionFlag_TestTableMask) == ExtensionFlag_TestTableMask; } + constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 3; } constexpr ALWAYS_INLINE KPhysicalAddress GetBlock() const { return this->SelectBits(12, 36); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index e5df6defb..b1a97fca0 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -37,11 +37,20 @@ namespace ams::kern::arch::arm64 { constexpr bool IsTailMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadTail) != 0; } }; - struct TraversalContext { - const L1PageTableEntry *l1_entry; - const L2PageTableEntry *l2_entry; - const L3PageTableEntry *l3_entry; + enum EntryLevel : u32 { + EntryLevel_L3 = 0, + EntryLevel_L2 = 1, + EntryLevel_L1 = 2, + EntryLevel_Count = 3, }; + + struct TraversalContext { + PageTableEntry *level_entries[EntryLevel_Count]; + EntryLevel level; + bool is_contiguous; + }; + + using EntryUpdatedCallback = void (*)(const void *); private: static constexpr size_t PageBits = util::CountTrailingZeros(PageSize); static constexpr size_t NumLevels = 3; @@ -53,11 +62,19 @@ namespace ams::kern::arch::arm64 { return (value >> Offset) & ((1ul << Count) - 1); } + static constexpr ALWAYS_INLINE u64 GetBits(u64 value, size_t offset, size_t count) { + return (value >> offset) & ((1ul << count) - 1); + } + template - constexpr ALWAYS_INLINE u64 SelectBits(u64 value) { + static constexpr ALWAYS_INLINE u64 SelectBits(u64 value) { return value & (((1ul << Count) - 1) << Offset); } + static constexpr ALWAYS_INLINE u64 SelectBits(u64 value, size_t offset, size_t count) { + return value & (((1ul << count) - 1) << offset); + } + static constexpr ALWAYS_INLINE uintptr_t GetL0Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL1Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL2Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } @@ -70,13 +87,14 @@ namespace ams::kern::arch::arm64 { static constexpr ALWAYS_INLINE uintptr_t GetContiguousL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2) + 4>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetContiguousL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3) + 4>(GetInteger(addr)); } + static constexpr ALWAYS_INLINE uintptr_t GetBlock(const PageTableEntry *pte, EntryLevel level) { return SelectBits(pte->GetRawAttributesUnsafe(), PageBits + LevelBits * level, LevelBits * (NumLevels + 1 - level)); } + static constexpr ALWAYS_INLINE uintptr_t GetOffset(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), 0, PageBits + LevelBits * level); } + static ALWAYS_INLINE KVirtualAddress GetPageTableVirtualAddress(KPhysicalAddress addr) { return KMemoryLayout::GetLinearVirtualAddress(addr); } - - ALWAYS_INLINE bool ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const; - ALWAYS_INLINE bool ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const; - ALWAYS_INLINE bool ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const; + public: + static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); } private: L1PageTableEntry *m_table; bool m_is_kernel; @@ -105,11 +123,17 @@ namespace ams::kern::arch::arm64 { ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KProcessAddress address) const { return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address); } + + static constexpr size_t GetBlockSize(EntryLevel level, bool contiguous = false) { + return 1 << (PageBits + LevelBits * level + 4 * contiguous); + } public: constexpr explicit KPageTableImpl(util::ConstantInitializeTag) : m_table(), m_is_kernel(), m_num_entries() { /* ... */ } explicit KPageTableImpl() { /* ... */ } + size_t GetNumL1Entries() const { return m_num_entries; } + NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end); NOINLINE void InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end); L1PageTableEntry *Finalize(); @@ -121,6 +145,17 @@ namespace ams::kern::arch::arm64 { bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const; bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const; + + static bool MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt); + void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const; + + KProcessAddress GetAddressForContext(const TraversalContext *context) const { + KProcessAddress addr = m_is_kernel ? static_cast(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0; + for (u32 level = context->level; level <= EntryLevel_L1; ++level) { + addr += ((reinterpret_cast(context->level_entries[level]) / sizeof(PageTableEntry)) & (BlocksPerTable - 1)) << (PageBits + LevelBits * level); + } + return addr; + } }; } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 640b9e5e5..e18a6fbc8 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -23,13 +23,13 @@ namespace ams::kern::arch::arm64 { private: KPageTable m_page_table; public: - void Activate(u64 id) { + void Activate(size_t process_index, u64 id) { /* Activate the page table with the specified contextidr. */ - m_page_table.Activate(id); + m_page_table.ActivateProcess(process_index, id); } - Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit)); + Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index)); } void Finalize() { m_page_table.Finalize(); } @@ -154,8 +154,8 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.InvalidateCurrentProcessDataCache(address, size)); } - Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { - R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size)); + Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod) { + R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size, force_debug_prod)); } Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp index 73d886d84..0c0602289 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp @@ -29,8 +29,7 @@ namespace ams::kern::arch::arm64 { NOINLINE void Initialize(s32 core_id); void Activate() { - /* Activate, using process id = 0xFFFFFFFF */ - m_page_table.Activate(0xFFFFFFFF); + m_page_table.ActivateKernel(); } void ActivateForInit() { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp index 202be5f51..17c6c6a44 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp @@ -21,38 +21,140 @@ namespace ams::kern::arch::arm64 { void UserspaceAccessFunctionAreaBegin(); class UserspaceAccess { + private: + class Impl { + public: + static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src); + static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src); + static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src); + static s32 CopyStringFromUser(void *dst, const void *src, size_t size); + + static bool CopyMemoryToUser(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserSize32Bit(void *dst, const void *src); + static s32 CopyStringToUser(void *dst, const void *src, size_t size); + + static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask); + static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value); + static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare); + + static bool StoreDataCache(uintptr_t start, uintptr_t end); + static bool FlushDataCache(uintptr_t start, uintptr_t end); + static bool InvalidateDataCache(uintptr_t start, uintptr_t end); + + static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size); + static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size); + static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size); + }; public: - static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src); - static s32 CopyStringFromUser(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUser(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUser(dst, src, size); + } - static bool CopyMemoryToUser(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserSize32Bit(void *dst, const void *src); - static s32 CopyStringToUser(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUserAligned32Bit(dst, src, size); + } - static bool ClearMemory(void *dst, size_t size); - static bool ClearMemoryAligned32Bit(void *dst, size_t size); - static bool ClearMemoryAligned64Bit(void *dst, size_t size); - static bool ClearMemorySize32Bit(void *dst); + static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUserAligned64Bit(dst, src, size); + } - static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask); - static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value); - static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare); + static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src) { + return Impl::CopyMemoryFromUserSize64Bit(dst, src); + } - static bool StoreDataCache(uintptr_t start, uintptr_t end); - static bool FlushDataCache(uintptr_t start, uintptr_t end); - static bool InvalidateDataCache(uintptr_t start, uintptr_t end); + static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src) { + return Impl::CopyMemoryFromUserSize32Bit(dst, src); + } - static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size); - static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size); - static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size); + + static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) { + /* Check that the address is within the valid userspace range. */ + if (const uintptr_t src_uptr = reinterpret_cast(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) { + return false; + } + + return Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(dst, src); + } + + static s32 CopyStringFromUser(void *dst, const void *src, size_t size) { + return Impl::CopyStringFromUser(dst, src, size); + } + + static bool CopyMemoryToUser(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUser(dst, src, size); + } + + static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUserAligned32Bit(dst, src, size); + } + + static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUserAligned64Bit(dst, src, size); + } + + static bool CopyMemoryToUserSize32Bit(void *dst, const void *src) { + return Impl::CopyMemoryToUserSize32Bit(dst, src); + } + + static s32 CopyStringToUser(void *dst, const void *src, size_t size) { + return Impl::CopyStringToUser(dst, src, size); + } + + static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) { + return Impl::UpdateLockAtomic(out, address, if_zero, new_orr_mask); + } + + static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) { + return Impl::UpdateIfEqualAtomic(out, address, compare_value, new_value); + } + + static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) { + return Impl::DecrementIfLessThanAtomic(out, address, compare); + } + + static bool StoreDataCache(uintptr_t start, uintptr_t end) { + return Impl::StoreDataCache(start, end); + } + + static bool FlushDataCache(uintptr_t start, uintptr_t end) { + return Impl::FlushDataCache(start, end); + } + + static bool InvalidateDataCache(uintptr_t start, uintptr_t end) { + return Impl::InvalidateDataCache(start, end); + } + + static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory32Bit(dst, src, size); + } + + static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory16Bit(dst, src, size); + } + + static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory8Bit(dst, src, size); + } + + static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory32Bit(dst, src, size); + } + + static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory16Bit(dst, src, size); + } + + static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory8Bit(dst, src, size); + } }; diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp index b12e8d02e..4e82780b0 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp @@ -24,4 +24,8 @@ namespace ams::kern { constexpr inline size_t MainMemorySize = 4_GB; constexpr inline size_t MainMemorySizeMax = 8_GB; + constexpr inline u32 MinimumMemoryManagerAlignmentShifts[] = { + 0, 0, 0, 0 + }; + } diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp index a0cfce5a1..8e1829849 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp @@ -45,6 +45,7 @@ namespace ams::kern::board::nintendo::nx { }; public: /* Initialization. */ + static NOINLINE void ConfigureKTargetSystem(); static NOINLINE void InitializePhase1(); static NOINLINE void InitializePhase2(); static NOINLINE u32 GetCreateProcessMemoryPool(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp index 4066de80d..f4ef74e6b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp @@ -39,14 +39,16 @@ namespace ams::kern { } } - Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s32 value, s64 timeout) { + Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s64 value, s64 timeout) { switch (type) { case ams::svc::ArbitrationType_WaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, value, false, timeout)); + R_RETURN(this->WaitIfLessThan(addr, static_cast(value), false, timeout)); case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, value, true, timeout)); + R_RETURN(this->WaitIfLessThan(addr, static_cast(value), true, timeout)); case ams::svc::ArbitrationType_WaitIfEqual: - R_RETURN(this->WaitIfEqual(addr, value, timeout)); + R_RETURN(this->WaitIfEqual(addr, static_cast(value), timeout)); + case ams::svc::ArbitrationType_WaitIfEqual64: + R_RETURN(this->WaitIfEqual64(addr, value, timeout)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } @@ -56,6 +58,7 @@ namespace ams::kern { Result SignalAndModifyByWaitingCountIfEqual(uintptr_t addr, s32 value, s32 count); Result WaitIfLessThan(uintptr_t addr, s32 value, bool decrement, s64 timeout); Result WaitIfEqual(uintptr_t addr, s32 value, s64 timeout); + Result WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout); }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp index 9e20dd254..775c0054c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp @@ -37,8 +37,8 @@ namespace ams::kern { size_t m_size; Type m_type; public: - static uintptr_t GetAddressSpaceStart(size_t width, Type type); - static size_t GetAddressSpaceSize(size_t width, Type type); + static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type, size_t code_size); + static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type); static void SetAddressSpaceSize(size_t width, Type type, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index 7c2f5dbcd..2c74b835c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -168,9 +168,10 @@ namespace ams::kern { struct DebugFlags { using IdBits = Field<0, CapabilityId + 1>; - DEFINE_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_FIELD(ForceDebug, AllowDebug, 1, bool); - DEFINE_FIELD(Reserved, ForceDebug, 13); + DEFINE_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_FIELD(ForceDebugProd, AllowDebug, 1, bool); + DEFINE_FIELD(ForceDebug, ForceDebugProd, 1, bool); + DEFINE_FIELD(Reserved, ForceDebug, 12); }; #undef DEFINE_FIELD @@ -255,6 +256,10 @@ namespace ams::kern { return m_debug_capabilities.Get(); } + constexpr bool CanForceDebugProd() const { + return m_debug_capabilities.Get(); + } + constexpr bool CanForceDebug() const { return m_debug_capabilities.Get(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp index 6c8fe54f7..6978b9152 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -32,6 +32,7 @@ namespace ams::kern { KLightLock m_lock; KProcess::State m_old_process_state; bool m_is_attached; + bool m_is_force_debug_prod; public: explicit KDebugBase() { /* ... */ } protected: @@ -62,6 +63,10 @@ namespace ams::kern { return m_is_attached; } + ALWAYS_INLINE bool IsForceDebugProd() const { + return m_is_force_debug_prod; + } + ALWAYS_INLINE bool OpenProcess() { return m_process_holder.Open(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index f021391e0..57876fbcb 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -200,7 +200,8 @@ namespace ams::kern { KMemoryBlockDisableMergeAttribute_DeviceLeft = (1u << 1), KMemoryBlockDisableMergeAttribute_IpcLeft = (1u << 2), KMemoryBlockDisableMergeAttribute_Locked = (1u << 3), - KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 4), + /* ... */ + KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 5), KMemoryBlockDisableMergeAttribute_AllLeft = KMemoryBlockDisableMergeAttribute_Normal | KMemoryBlockDisableMergeAttribute_DeviceLeft | KMemoryBlockDisableMergeAttribute_IpcLeft | KMemoryBlockDisableMergeAttribute_Locked, KMemoryBlockDisableMergeAttribute_AllRight = KMemoryBlockDisableMergeAttribute_DeviceRight, @@ -288,18 +289,18 @@ namespace ams::kern { class KMemoryBlock : public util::IntrusiveRedBlackTreeBaseNode { private: - u16 m_device_disable_merge_left_count; - u16 m_device_disable_merge_right_count; - KProcessAddress m_address; - size_t m_num_pages; - KMemoryState m_memory_state; - u16 m_ipc_lock_count; - u16 m_device_use_count; - u16 m_ipc_disable_merge_count; KMemoryPermission m_permission; KMemoryPermission m_original_permission; KMemoryAttribute m_attribute; KMemoryBlockDisableMergeAttribute m_disable_merge_attribute; + KProcessAddress m_address; + u32 m_num_pages; + KMemoryState m_memory_state; + u16 m_ipc_lock_count; + u16 m_ipc_disable_merge_count; + u16 m_device_use_count; + u16 m_device_disable_merge_left_count; + u16 m_device_disable_merge_right_count; public: static constexpr ALWAYS_INLINE int Compare(const KMemoryBlock &lhs, const KMemoryBlock &rhs) { if (lhs.GetAddress() < rhs.GetAddress()) { @@ -343,6 +344,10 @@ namespace ams::kern { return m_ipc_disable_merge_count; } + constexpr u16 GetDeviceUseCount() const { + return m_device_use_count; + } + constexpr KMemoryPermission GetPermission() const { return m_permission; } @@ -374,16 +379,15 @@ namespace ams::kern { public: explicit KMemoryBlock() { /* ... */ } - constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) - : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_device_disable_merge_left_count(), - m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), - m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), - m_attribute(attr), m_disable_merge_attribute() + constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) + : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_permission(p), m_original_permission(KMemoryPermission_None), + m_attribute(attr), m_disable_merge_attribute(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), + m_ipc_disable_merge_count(), m_device_use_count(0), m_device_disable_merge_left_count(), m_device_disable_merge_right_count() { /* ... */ } - constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { + constexpr void Initialize(KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { MESOSPHERE_ASSERT_THIS(); m_device_disable_merge_left_count = 0; m_device_disable_merge_right_count = 0; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp index 4a67e86f5..f2888ec65 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp @@ -99,6 +99,7 @@ namespace ams::kern { Result Initialize(KProcessAddress st, KProcessAddress nd, KMemoryBlockSlabManager *slab_manager); void Finalize(KMemoryBlockSlabManager *slab_manager); + static bool GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages); 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, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index bd596dfd0..99ef1f6b5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -164,6 +164,7 @@ namespace ams::kern { size_t m_num_managers; u64 m_optimized_process_ids[Pool_Count]; bool m_has_optimized_process[Pool_Count]; + s32 m_min_heap_indexes[Pool_Count]; private: Impl &GetManager(KPhysicalAddress address) { return m_managers[KMemoryLayout::GetPhysicalLinearRegion(address).GetAttributes()]; @@ -188,12 +189,12 @@ namespace ams::kern { Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index); public: KMemoryManager() - : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process() + : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process(), m_min_heap_indexes() { /* ... */ } - NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size); + NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts); NOINLINE Result InitializeOptimizedMemory(u64 process_id, Pool pool); NOINLINE void FinalizeOptimizedMemory(u64 process_id, Pool pool); @@ -299,6 +300,10 @@ namespace ams::kern { manager->DumpFreeList(); } } + + size_t GetMinimumAlignment(Pool pool) { + return KPageHeap::GetBlockSize(m_min_heap_indexes[pool]); + } public: static size_t CalculateManagementOverheadSize(size_t region_size) { return Impl::CalculateManagementOverheadSize(region_size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 99a27c6f9..7b2c722e1 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -318,7 +318,7 @@ namespace ams::kern { R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr)); } - Result CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const; + Result CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const; Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const { @@ -328,6 +328,8 @@ namespace ams::kern { R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); } + bool CanReadWriteDebugMemory(KProcessAddress addr, size_t size, bool force_debug_prod); + Result LockMemoryAndOpen(KPageGroup *out_pg, KPhysicalAddress *out_paddr, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr); Result UnlockMemory(KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr, const KPageGroup *pg); @@ -421,7 +423,7 @@ namespace ams::kern { Result InvalidateProcessDataCache(KProcessAddress address, size_t size); Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size); - Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); + Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod); Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state); Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 3258d41e2..849f73dab 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -206,6 +206,10 @@ namespace ams::kern { return m_capabilities.IsPermittedDebug(); } + constexpr bool CanForceDebugProd() const { + return m_capabilities.CanForceDebugProd(); + } + constexpr bool CanForceDebug() const { return m_capabilities.CanForceDebug(); } @@ -360,7 +364,7 @@ namespace ams::kern { R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count)); } - Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s32 value, s64 timeout) { + Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s64 value, s64 timeout) { R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout)); } @@ -374,7 +378,7 @@ namespace ams::kern { /* Update the current page table. */ if (next_process) { - next_process->GetPageTable().Activate(next_process->GetProcessId()); + next_process->GetPageTable().Activate(next_process->GetSlabIndex(), next_process->GetProcessId()); } else { Kernel::GetKernelPageTable().Activate(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp index bb1c1ff0f..3d7ea5310 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp @@ -41,7 +41,7 @@ namespace ams::kern { /* Nintendo uses std::mt19937_t for randomness. */ /* To save space (and because mt19337_t isn't secure anyway), */ /* We will use TinyMT. */ - static constinit inline bool s_initialized_random_generator; + static constinit inline bool s_uninitialized_random_generator{true}; static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize}; static constinit inline KSpinLock s_random_lock; public: @@ -69,6 +69,7 @@ namespace ams::kern { static NOINLINE void InitializePhase1Base(u64 seed); public: /* Initialization. */ + static NOINLINE void ConfigureKTargetSystem(); static NOINLINE void InitializePhase1(); static NOINLINE void InitializePhase2(); static NOINLINE u32 GetCreateProcessMemoryPool(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp index d0ba5ca10..628d1724b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp @@ -94,7 +94,11 @@ namespace ams::kern { static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const { - return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); + if (m_resource_limit != nullptr) { + return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); + } else { + return 0; + } } ALWAYS_INLINE size_t GetSize() const { return m_resource_size; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp index 87b72c0fa..949fd45ba 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp @@ -24,29 +24,36 @@ namespace ams::kern { friend class KSystemControlBase; friend class KSystemControl; private: - static inline constinit bool s_is_debug_mode; - static inline constinit bool s_enable_debug_logging; - static inline constinit bool s_enable_user_exception_handlers; - static inline constinit bool s_enable_debug_memory_fill; - static inline constinit bool s_enable_user_pmu_access; - static inline constinit bool s_enable_kernel_debugging; - static inline constinit bool s_enable_dynamic_resource_limits; + struct KTargetSystemData { + bool is_not_debug_mode; + bool disable_debug_logging; + bool disable_user_exception_handlers; + bool disable_debug_memory_fill; + bool disable_user_pmu_access; + bool disable_kernel_debugging; + bool disable_dynamic_resource_limits; + }; private: - static ALWAYS_INLINE void SetIsDebugMode(bool en) { s_is_debug_mode = en; } - static ALWAYS_INLINE void EnableDebugLogging(bool en) { s_enable_debug_logging = en; } - static ALWAYS_INLINE void EnableUserExceptionHandlers(bool en) { s_enable_user_exception_handlers = en; } - static ALWAYS_INLINE void EnableDebugMemoryFill(bool en) { s_enable_debug_memory_fill = en; } - static ALWAYS_INLINE void EnableUserPmuAccess(bool en) { s_enable_user_pmu_access = en; } - static ALWAYS_INLINE void EnableKernelDebugging(bool en) { s_enable_kernel_debugging = en; } - static ALWAYS_INLINE void EnableDynamicResourceLimits(bool en) { s_enable_dynamic_resource_limits = en; } + static inline constinit bool s_is_uninitialized = true; + static inline constinit const volatile KTargetSystemData s_data = { + .is_not_debug_mode = false, + .disable_debug_logging = false, + .disable_user_exception_handlers = false, + .disable_debug_memory_fill = false, + .disable_user_pmu_access = false, + .disable_kernel_debugging = false, + .disable_dynamic_resource_limits = true, + }; + private: + static ALWAYS_INLINE void SetInitialized() { s_is_uninitialized = false; } public: - static ALWAYS_INLINE bool IsDebugMode() { return s_is_debug_mode; } - static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_enable_debug_logging; } - static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_enable_user_exception_handlers; } - static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_enable_debug_memory_fill; } - static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_enable_user_pmu_access; } - static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_enable_kernel_debugging; } - static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_enable_dynamic_resource_limits; } + static ALWAYS_INLINE bool IsDebugMode() { return !(s_is_uninitialized | s_data.is_not_debug_mode); } + static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return !(s_is_uninitialized | s_data.disable_debug_logging); } + static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return !(s_is_uninitialized | s_data.disable_user_exception_handlers); } + static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return !(s_is_uninitialized | s_data.disable_debug_memory_fill); } + static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return !(s_is_uninitialized | s_data.disable_user_pmu_access); } + static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return !(s_is_uninitialized | s_data.disable_kernel_debugging); } + static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return !(s_is_uninitialized | s_data.disable_dynamic_resource_limits); } }; } \ No newline at end of file diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp index cd88f3abf..c34ceb8c3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp @@ -48,6 +48,22 @@ namespace ams::kern { KProcess *GetOwner() const { return m_owner; } KProcessAddress GetSourceAddress() { return m_address; } size_t GetSize() const { return m_is_initialized ? GetReference(m_page_group).GetNumPages() * PageSize : 0; } + + constexpr uintptr_t GetHint() const { + /* Get memory size. */ + const size_t size = this->GetSize(); + + /* TODO: Is this architecture specific? */ + if (size >= 2_MB) { + return GetInteger(m_address) & (2_MB - 1); + } else if (size >= 64_KB) { + return GetInteger(m_address) & (64_KB - 1); + } else if (size >= 4_KB) { + return GetInteger(m_address) & (4_KB - 1); + } else { + return 0; + } + } }; } diff --git a/libraries/libmesosphere/libmesosphere.mk b/libraries/libmesosphere/libmesosphere.mk index 32db70664..79c2c13ed 100644 --- a/libraries/libmesosphere/libmesosphere.mk +++ b/libraries/libmesosphere/libmesosphere.mk @@ -20,7 +20,7 @@ endif DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) -CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto +CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) SOURCES += $(foreach v,$(call ALL_SOURCE_DIRS,../libvapours/source),$(if $(findstring ../libvapours/source/sdmmc,$v),,$v)) diff --git a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc index 864da44a5..ef363c0cf 100644 --- a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc +++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc @@ -79,6 +79,12 @@ namespace ams::kern::arch::arm { /* Setup all interrupt lines. */ SetupInterruptLines(core_id); + + /* Clear pointers, if needed. */ + if (core_id == 0) { + m_gicd = nullptr; + m_gicc = nullptr; + } } void KInterruptController::SaveCoreLocal(LocalState *state) const { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index d55e217e3..6c21b455b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -100,6 +100,8 @@ namespace ams::kern::arch::arm64 { u32 insn_value = 0; if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_value), reinterpret_cast(context->pc), sizeof(insn_value))) { insn = insn_value; + } else if (KTargetSystem::IsDebugMode() && (context->pc & 3) == 0 && UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccess(std::addressof(insn_value), reinterpret_cast(context->pc))) { + insn = insn_value; } else { insn = 0; } @@ -107,39 +109,31 @@ namespace ams::kern::arch::arm64 { return insn; } - void HandleUserException(KExceptionContext *context, u64 esr, u64 far, u64 afsr0, u64 afsr1, u32 data) { + void HandleUserException(KExceptionContext *context, u64 raw_esr, u64 raw_far, u64 afsr0, u64 afsr1, u32 data) { + /* Pre-process exception registers as needed. */ + u64 esr = raw_esr; + u64 far = raw_far; + const u64 ec = (esr >> 26) & 0x3F; + if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { + /* Adjust registers if a synchronous external abort has occurred with far not valid. */ + /* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */ + /* not on translation table walk or hardware update of translation table. */ + /* Mask 0x400 = FnV = "FAR Not Valid" */ + /* TODO: How would we perform this check using named register accesses? */ + if ((esr & 0x43F) == 0x410) { + /* Clear the faulting register on memory tagging exception. */ + far = 0; + } else { + /* If the faulting address is a kernel address, set ISFC = 4. */ + if (far >= ams::svc::AddressMemoryRegion39Size) { + esr = (esr & 0xFFFFFFC0) | 4; + } + } + } + KProcess &cur_process = GetCurrentProcess(); bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled(); - const u64 ec = (esr >> 26) & 0x3F; - switch (ec) { - case EsrEc_Unknown: - case EsrEc_IllegalExecution: - case EsrEc_Svc32: - case EsrEc_Svc64: - case EsrEc_PcAlignmentFault: - case EsrEc_SpAlignmentFault: - case EsrEc_SErrorInterrupt: - case EsrEc_BreakPointEl0: - case EsrEc_SoftwareStepEl0: - case EsrEc_WatchPointEl0: - case EsrEc_BkptInstruction: - case EsrEc_BrkInstruction: - break; - default: - { - /* If the fault address's state is KMemoryState_Code and the user can't read the address, force processing exception. */ - KMemoryInfo info; - ams::svc::PageInfo pi; - if (R_SUCCEEDED(cur_process.GetPageTable().QueryInfo(std::addressof(info), std::addressof(pi), far))) { - if (info.GetState() == KMemoryState_Code && ((info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead)) { - should_process_user_exception = true; - } - } - } - break; - } - /* In the event that we return from this exception, we want SPSR.SS set so that we advance an instruction if single-stepping. */ #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) context->psr |= (1ul << 21); @@ -190,7 +184,7 @@ namespace ams::kern::arch::arm64 { } /* Save the debug parameters to the current thread. */ - GetCurrentThread().SaveDebugParams(far, esr, data); + GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data); /* Get the exception type. */ u32 type; @@ -412,7 +406,6 @@ namespace ams::kern::arch::arm64 { ams::svc::aarch32::ExceptionInfo info32; } info = {}; - const bool is_aarch64 = (e_ctx->psr & 0x10) == 0; if (is_aarch64) { /* We're 64-bit. */ @@ -457,9 +450,28 @@ namespace ams::kern::arch::arm64 { uintptr_t far, esr, data; GetCurrentThread().RestoreDebugParams(std::addressof(far), std::addressof(esr), std::addressof(data)); + /* Pre-process exception registers as needed. */ + const u64 ec = (esr >> 26) & 0x3F; + if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { + /* Adjust registers if a synchronous external abort has occurred with far not valid. */ + /* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */ + /* not on translation table walk or hardware update of translation table. */ + /* Mask 0x400 = FnV = "FAR Not Valid" */ + /* TODO: How would we perform this check using named register accesses? */ + if ((esr & 0x43F) == 0x410) { + /* Clear the faulting register on memory tagging exception. */ + far = 0; + } else { + /* If the faulting address is a kernel address, set ISFC = 4. */ + if (far >= ams::svc::AddressMemoryRegion39Size) { + esr = (esr & 0xFFFFFFC0) | 4; + } + } + } + /* Collect additional information based on the ec. */ uintptr_t params[3] = {}; - switch ((esr >> 26) & 0x3F) { + switch (ec) { case EsrEc_Unknown: case EsrEc_IllegalExecution: case EsrEc_BkptInstruction: diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 89587597b..87d7bf307 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -15,6 +15,28 @@ */ #include +/* */ +namespace ams::rocrt { + + constexpr inline const u32 ModuleHeaderVersion = util::FourCC<'M','O','D','0'>::Code; + + struct ModuleHeader { + u32 signature; + u32 dynamic_offset; + u32 bss_start_offset; + u32 bss_end_offset; + u32 exception_info_start_offset; + u32 exception_info_end_offset; + u32 module_offset; + }; + + struct ModuleHeaderLocation { + u32 pad; + u32 header_offset; + }; + +} + namespace ams::kern::arch::arm64 { namespace { @@ -657,7 +679,7 @@ namespace ams::kern::arch::arm64 { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - dyn_address = module.start_address + mod_offset + temp_32; + dyn_address = base_address + mod_offset + temp_32; } /* Locate tables inside .dyn. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 55e4fc52b..abc3b1076 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -85,77 +85,6 @@ namespace ams::kern::arch::arm64 { return (static_cast(asid) << 48) | (static_cast(GetInteger(table))); } - class KPageTableAsidManager { - private: - using WordType = u32; - static constexpr u8 ReservedAsids[] = { 0 }; - static constexpr size_t NumReservedAsids = util::size(ReservedAsids); - static constexpr size_t BitsPerWord = BITSIZEOF(WordType); - static constexpr size_t AsidCount = 0x100; - static constexpr size_t NumWords = AsidCount / BitsPerWord; - static constexpr WordType FullWord = ~WordType(0u); - private: - WordType m_state[NumWords]; - KLightLock m_lock; - u8 m_hint; - private: - constexpr bool TestImpl(u8 asid) const { - return m_state[asid / BitsPerWord] & (1u << (asid % BitsPerWord)); - } - constexpr void ReserveImpl(u8 asid) { - MESOSPHERE_ASSERT(!this->TestImpl(asid)); - m_state[asid / BitsPerWord] |= (1u << (asid % BitsPerWord)); - } - - constexpr void ReleaseImpl(u8 asid) { - MESOSPHERE_ASSERT(this->TestImpl(asid)); - m_state[asid / BitsPerWord] &= ~(1u << (asid % BitsPerWord)); - } - - constexpr u8 FindAvailable() const { - for (size_t i = 0; i < util::size(m_state); i++) { - if (m_state[i] == FullWord) { - continue; - } - const WordType clear_bit = (m_state[i] + 1) ^ (m_state[i]); - return BitsPerWord * i + BitsPerWord - 1 - ClearLeadingZero(clear_bit); - } - if (m_state[util::size(m_state)-1] == FullWord) { - MESOSPHERE_PANIC("Unable to reserve ASID"); - } - __builtin_unreachable(); - } - - static constexpr ALWAYS_INLINE WordType ClearLeadingZero(WordType value) { - return __builtin_clzll(value) - (BITSIZEOF(unsigned long long) - BITSIZEOF(WordType)); - } - public: - constexpr KPageTableAsidManager() : m_state(), m_lock(), m_hint() { - for (size_t i = 0; i < NumReservedAsids; i++) { - this->ReserveImpl(ReservedAsids[i]); - } - } - - u8 Reserve() { - KScopedLightLock lk(m_lock); - - if (this->TestImpl(m_hint)) { - m_hint = this->FindAvailable(); - } - - this->ReserveImpl(m_hint); - - return m_hint++; - } - - void Release(u8 asid) { - KScopedLightLock lk(m_lock); - this->ReleaseImpl(asid); - } - }; - - KPageTableAsidManager g_asid_manager; - } ALWAYS_INLINE void KPageTable::NoteUpdated() const { @@ -184,6 +113,7 @@ namespace ams::kern::arch::arm64 { this->OnKernelTableSinglePageUpdated(virt_addr); } + void KPageTable::Initialize(s32 core_id) { /* Nothing actually needed here. */ MESOSPHERE_UNUSED(core_id); @@ -194,38 +124,29 @@ namespace ams::kern::arch::arm64 { m_asid = 0; m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer(); - /* Allocate a page for ttbr. */ - /* NOTE: It is a postcondition of page table manager allocation that the page is all-zero. */ - const u64 asid_tag = (static_cast(m_asid) << 48ul); - const KVirtualAddress page = m_manager->Allocate(); - MESOSPHERE_ASSERT(page != Null); - m_ttbr = GetInteger(KPageTableBase::GetLinearMappedPhysicalAddress(page)) | asid_tag; - /* Initialize the base page table. */ MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end)); R_SUCCEED(); } - Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - /* Get an ASID */ - m_asid = g_asid_manager.Reserve(); - ON_RESULT_FAILURE { g_asid_manager.Release(m_asid); }; + Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + /* Determine our ASID */ + m_asid = process_index + 1; + MESOSPHERE_ABORT_UNLESS(0 < m_asid && m_asid < util::size(s_ttbr0_entries)); /* Set our manager. */ m_manager = system_resource->GetPageTableManagerPointer(); - /* Allocate a new table, and set our ttbr value. */ - const KVirtualAddress new_table = m_manager->Allocate(); - R_UNLESS(new_table != Null, svc::ResultOutOfResource()); - m_ttbr = EncodeTtbr(GetPageTablePhysicalAddress(new_table), m_asid); - ON_RESULT_FAILURE_2 { m_manager->Free(new_table); }; + /* Get the virtual address of our L1 table. */ + const KPhysicalAddress ttbr0_phys = KPhysicalAddress(s_ttbr0_entries[m_asid] & UINT64_C(0xFFFFFFFFFFFE)); + const KVirtualAddress ttbr0_virt = KMemoryLayout::GetLinearVirtualAddress(ttbr0_phys); /* Initialize our base table. */ const size_t as_width = GetAddressSpaceWidth(flags); const KProcessAddress as_start = 0; const KProcessAddress as_end = (1ul << as_width); - R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(new_table), as_start, as_end, code_address, code_size, system_resource, resource_limit)); + R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(ttbr0_virt), as_start, as_end, code_address, code_size, system_resource, resource_limit)); /* Note that we've updated the table (since we created it). */ this->NoteUpdated(); @@ -253,96 +174,104 @@ namespace ams::kern::arch::arm64 { /* Traverse, freeing all pages. */ { - /* Get the address space size. */ - const size_t as_size = this->GetAddressSpaceSize(); - /* Begin the traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; - bool cur_valid = false; - TraversalEntry next_entry; - bool next_valid; - size_t tot_size = 0; + TraversalEntry entry; - next_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), this->GetAddressSpaceStart()); + KPhysicalAddress cur_phys_addr = Null; + size_t cur_size = 0; + u8 has_attr = 0; - /* Iterate over entries. */ + bool cur_valid = impl.BeginTraversal(std::addressof(entry), std::addressof(context), this->GetAddressSpaceStart()); while (true) { - /* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */ - /* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */ - if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size && next_entry.attr == (cur_entry.attr ? 1 : 0))) { - cur_entry.block_size += next_entry.block_size; - } else { - if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { - mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); + if (cur_valid) { + /* Free the actual pages, if there are any. */ + if (IsHeapPhysicalAddressForFinalize(entry.phys_addr)) { + if (cur_size > 0) { + /* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */ + /* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */ + if (entry.phys_addr == cur_phys_addr + cur_size && entry.attr == has_attr) { + /* Just extend the block, since we can. */ + cur_size += entry.block_size; + } else { + /* Close the block, and begin tracking anew. */ + mm.Close(cur_phys_addr, cur_size / PageSize); + + cur_phys_addr = entry.phys_addr; + cur_size = entry.block_size; + has_attr = entry.attr != 0; + } + } else { + cur_phys_addr = entry.phys_addr; + cur_size = entry.block_size; + has_attr = entry.attr != 0; + } } - /* Update tracking variables. */ - tot_size += cur_entry.block_size; - cur_entry = next_entry; - cur_valid = next_valid; + /* Clean up the page table entries. */ + bool freeing_table = false; + while (true) { + /* Clear the entries. */ + const size_t num_to_clear = (!freeing_table && context.is_contiguous) ? BlocksPerContiguousBlock : 1; + auto *pte = reinterpret_cast(context.is_contiguous ? util::AlignDown(reinterpret_cast(context.level_entries[context.level]), BlocksPerContiguousBlock * sizeof(PageTableEntry)) : reinterpret_cast(context.level_entries[context.level])); + for (size_t i = 0; i < num_to_clear; ++i) { + pte[i] = InvalidPageTableEntry; + } + + /* Remove the entries from the previous table. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->CloseTableReferences(num_to_clear); + } + + /* If we cleared a table, we need to note that we updated and free the table. */ + if (freeing_table) { + KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize)); + if (table == Null) { + break; + } + ClearPageTable(table); + this->GetPageTableManager().Free(table); + } + + /* Advance; we're no longer contiguous. */ + context.is_contiguous = false; + context.level_entries[context.level] = pte + num_to_clear - 1; + + /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { + break; + } + + /* Advance; we will not be working with blocks any more. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + freeing_table = true; + } } - if (cur_entry.block_size + tot_size >= as_size) { + /* Continue the traversal. */ + cur_valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); + + if (entry.block_size == 0) { break; } - - next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); } - /* Handle the last block. */ - if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { - mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); + /* Free any remaining pages. */ + if (cur_size > 0) { + mm.Close(cur_phys_addr, cur_size / PageSize); } } - /* Cache address space extents for convenience. */ - const KProcessAddress as_start = this->GetAddressSpaceStart(); - const KProcessAddress as_last = as_start + this->GetAddressSpaceSize() - 1; - - /* Free all L3 tables. */ - for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L2BlockSize) { - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address); - if (l1_entry->IsTable()) { - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, cur_address); - if (l2_entry->IsTable()) { - const KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable()); - if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) { - while (!this->GetPageTableManager().Close(l3_table, 1)) { /* ... */ } - ClearPageTable(l3_table); - this->GetPageTableManager().Free(l3_table); - } - } - } - } - - /* Free all L2 tables. */ - for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L1BlockSize) { - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address); - if (l1_entry->IsTable()) { - const KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable()); - if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) { - while (!this->GetPageTableManager().Close(l2_table, 1)) { /* ... */ } - ClearPageTable(l2_table); - this->GetPageTableManager().Free(l2_table); - } - } - } - - /* Free the L1 table. */ + /* Clear the L1 table. */ { const KVirtualAddress l1_table = reinterpret_cast(impl.Finalize()); ClearPageTable(l1_table); - this->GetPageTableManager().Free(l1_table); } /* Perform inherited finalization. */ KPageTableBase::Finalize(); } - /* Release our asid. */ - g_asid_manager.Release(m_asid); - R_SUCCEED(); } @@ -363,23 +292,16 @@ namespace ams::kern::arch::arm64 { if (operation == OperationType_Unmap) { R_RETURN(this->Unmap(virt_addr, num_pages, page_list, false, reuse_ll)); } else if (operation == OperationType_Separate) { - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } - - R_SUCCEED(); + R_RETURN(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); } else { auto entry_template = this->GetEntryTemplate(properties); switch (operation) { case OperationType_Map: + /* If mapping io or uncached pages, ensure that there is no pending reschedule. */ + if (properties.io || properties.uncached) { + KScopedSchedulerLock sl; + } R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, page_list, reuse_ll)); case OperationType_ChangePermissions: R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, false, false, page_list, reuse_ll)); @@ -404,214 +326,26 @@ namespace ams::kern::arch::arm64 { switch (operation) { case OperationType_MapGroup: case OperationType_MapFirstGroup: + /* If mapping io or uncached pages, ensure that there is no pending reschedule. */ + if (properties.io || properties.uncached) { + KScopedSchedulerLock sl; + } R_RETURN(this->MapGroup(virt_addr, page_group, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirstGroup, page_list, reuse_ll)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } - Result KPageTable::MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), L1BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(num_pages * PageSize, L1BlockSize)); - - /* Allocation is never needed for L1 block mapping. */ - MESOSPHERE_UNUSED(page_list, reuse_ll); - - auto &impl = this->GetImpl(); - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each block. */ - for (size_t i = 0; i < num_pages; i += L1BlockSize / PageSize) { - /* Map the block. */ - *impl.GetL1Entry(virt_addr) = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - virt_addr += L1BlockSize; - phys_addr += L1BlockSize; - } - - R_SUCCEED(); - } - - Result KPageTable::MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), L2BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), L2BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(num_pages * PageSize, L2BlockSize)); - - auto &impl = this->GetImpl(); - KVirtualAddress l2_virt = Null; - int l2_open_count = 0; - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each block. */ - for (size_t i = 0; i < num_pages; i += L2BlockSize / PageSize) { - KPhysicalAddress l2_phys = Null; - - /* If we have no L2 table, we should get or allocate one. */ - if (l2_virt == Null) { - if (L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); !l1_entry->GetTable(l2_phys)) { - /* Allocate table. */ - l2_virt = AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_virt != Null, svc::ResultOutOfResource()); - - /* Set the entry. */ - l2_phys = GetPageTablePhysicalAddress(l2_virt); - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); - } else { - l2_virt = GetPageTableVirtualAddress(l2_phys); - } - } - MESOSPHERE_ASSERT(l2_virt != Null); - - /* Map the block. */ - *impl.GetL2EntryFromTable(l2_virt, virt_addr) = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - l2_open_count++; - virt_addr += L2BlockSize; - phys_addr += L2BlockSize; - - /* Account for hitting end of table. */ - if (util::IsAligned(GetInteger(virt_addr), L1BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - l2_virt = Null; - l2_open_count = 0; - } - } - - /* Perform any remaining opens. */ - if (l2_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - - R_SUCCEED(); - } - - Result KPageTable::MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); - - auto &impl = this->GetImpl(); - KVirtualAddress l2_virt = Null; - KVirtualAddress l3_virt = Null; - int l2_open_count = 0; - int l3_open_count = 0; - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each page. */ - for (size_t i = 0; i < num_pages; i++) { - KPhysicalAddress l3_phys = Null; - bool l2_allocated = false; - - /* If we have no L3 table, we should get or allocate one. */ - if (l3_virt == Null) { - KPhysicalAddress l2_phys = Null; - - /* If we have no L2 table, we should get or allocate one. */ - if (l2_virt == Null) { - if (L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); !l1_entry->GetTable(l2_phys)) { - /* Allocate table. */ - l2_virt = AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_virt != Null, svc::ResultOutOfResource()); - - /* Set the entry. */ - l2_phys = GetPageTablePhysicalAddress(l2_virt); - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); - l2_allocated = true; - } else { - l2_virt = GetPageTableVirtualAddress(l2_phys); - } - } - MESOSPHERE_ASSERT(l2_virt != Null); - - if (L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, virt_addr); !l2_entry->GetTable(l3_phys)) { - /* Allocate table. */ - l3_virt = AllocatePageTable(page_list, reuse_ll); - if (l3_virt == Null) { - /* Cleanup the L2 entry. */ - if (l2_allocated) { - *impl.GetL1Entry(virt_addr) = InvalidL1PageTableEntry; - this->NoteUpdated(); - FreePageTable(page_list, l2_virt); - } else if (this->GetPageTableManager().IsInPageTableHeap(l2_virt) && l2_open_count > 0) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - - R_THROW(svc::ResultOutOfResource()); - } - - /* Set the entry. */ - l3_phys = GetPageTablePhysicalAddress(l3_virt); - PteDataMemoryBarrier(); - *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, l3_phys, this->IsKernel(), true); - l2_open_count++; - } else { - l3_virt = GetPageTableVirtualAddress(l3_phys); - } - } - MESOSPHERE_ASSERT(l3_virt != Null); - - /* Map the page. */ - *impl.GetL3EntryFromTable(l3_virt, virt_addr) = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - l3_open_count++; - virt_addr += PageSize; - phys_addr += PageSize; - - /* Account for hitting end of table. */ - if (util::IsAligned(GetInteger(virt_addr), L2BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - this->GetPageTableManager().Open(l3_virt, l3_open_count); - } - l3_virt = Null; - l3_open_count = 0; - - if (util::IsAligned(GetInteger(virt_addr), L1BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt) && l2_open_count > 0) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - l2_virt = Null; - l2_open_count = 0; - } - } - } - - /* Perform any remaining opens. */ - if (l2_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - if (l3_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - this->GetPageTableManager().Open(l3_virt, l3_open_count); - } - - R_SUCCEED(); - } - Result KPageTable::Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* Ensure there are no pending data writes. */ + cpu::DataSynchronizationBarrier(); + auto &impl = this->GetImpl(); /* If we're not forcing an unmap, separate pages immediately. */ if (!force) { - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } + R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); } /* Cache initial addresses for use on cleanup. */ @@ -641,10 +375,7 @@ namespace ams::kern::arch::arm64 { /* Handle the case where the block is bigger than it should be. */ if (next_entry.block_size > remaining_pages * PageSize) { MESOSPHERE_ABORT_UNLESS(force); - MESOSPHERE_R_ABORT_UNLESS(this->SeparatePages(virt_addr, remaining_pages * PageSize, page_list, reuse_ll)); - const bool new_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), virt_addr); - MESOSPHERE_ASSERT(new_valid); - MESOSPHERE_UNUSED(new_valid); + MESOSPHERE_R_ABORT_UNLESS(this->SeparatePagesImpl(std::addressof(next_entry), std::addressof(context), virt_addr, remaining_pages * PageSize, page_list, reuse_ll)); } /* Check that our state is coherent. */ @@ -652,87 +383,45 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(next_entry.phys_addr), next_entry.block_size)); /* Unmap the block. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - switch (next_entry.block_size) { - case L1BlockSize: - { - /* Clear the entry. */ - *l1_entry = InvalidL1PageTableEntry; + bool freeing_table = false; + bool need_recalculate_virt_addr = false; + while (true) { + /* Clear the entries. */ + const size_t num_to_clear = (!freeing_table && context.is_contiguous) ? BlocksPerContiguousBlock : 1; + auto *pte = reinterpret_cast(context.is_contiguous ? util::AlignDown(reinterpret_cast(context.level_entries[context.level]), BlocksPerContiguousBlock * sizeof(PageTableEntry)) : reinterpret_cast(context.level_entries[context.level])); + for (size_t i = 0; i < num_to_clear; ++i) { + pte[i] = InvalidPageTableEntry; + } + + /* Remove the entries from the previous table. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->CloseTableReferences(num_to_clear); + } + + /* If we cleared a table, we need to note that we updated and free the table. */ + if (freeing_table) { + /* If there's no table, we also don't need to do a free. */ + const KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize)); + if (table == Null) { + break; } + this->NoteUpdated(); + this->FreePageTable(page_list, table); + need_recalculate_virt_addr = true; + } + + /* Advance; we're no longer contiguous. */ + context.is_contiguous = false; + context.level_entries[context.level] = pte + num_to_clear - 1; + + /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { break; - case L2ContiguousBlockSize: - case L2BlockSize: - { - /* Get the number of L2 blocks. */ - const size_t num_l2_blocks = next_entry.block_size / L2BlockSize; + } - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - - /* Clear the entry. */ - for (size_t i = 0; i < num_l2_blocks; i++) { - *impl.GetL2EntryFromTable(l2_virt, virt_addr + L2BlockSize * i) = InvalidL2PageTableEntry; - } - PteDataMemoryBarrier(); - - /* Close references to the L2 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - if (this->GetPageTableManager().Close(l2_virt, num_l2_blocks)) { - *l1_entry = InvalidL1PageTableEntry; - this->NoteUpdated(); - this->FreePageTable(page_list, l2_virt); - pages_to_close.CloseAndReset(); - } - } - } - break; - case L3ContiguousBlockSize: - case L3BlockSize: - { - /* Get the number of L3 blocks. */ - const size_t num_l3_blocks = next_entry.block_size / L3BlockSize; - - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, virt_addr); - - /* Get the L3 entry. */ - KPhysicalAddress l3_phys = Null; - MESOSPHERE_ABORT_UNLESS(l2_entry->GetTable(l3_phys)); - const KVirtualAddress l3_virt = GetPageTableVirtualAddress(l3_phys); - - /* Clear the entry. */ - for (size_t i = 0; i < num_l3_blocks; i++) { - *impl.GetL3EntryFromTable(l3_virt, virt_addr + L3BlockSize * i) = InvalidL3PageTableEntry; - } - PteDataMemoryBarrier(); - - /* Close references to the L3 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - if (this->GetPageTableManager().Close(l3_virt, num_l3_blocks)) { - *l2_entry = InvalidL2PageTableEntry; - this->NoteUpdated(); - - /* Close reference to the L2 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - if (this->GetPageTableManager().Close(l2_virt, 1)) { - *l1_entry = InvalidL1PageTableEntry; - this->NoteUpdated(); - this->FreePageTable(page_list, l2_virt); - } - } - - this->FreePageTable(page_list, l3_virt); - pages_to_close.CloseAndReset(); - } - } - } - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + /* Advance; we will not be working with blocks any more. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + freeing_table = true; } /* Close the blocks. */ @@ -746,8 +435,20 @@ namespace ams::kern::arch::arm64 { } /* Advance. */ - virt_addr += next_entry.block_size; - remaining_pages -= next_entry.block_size / PageSize; + size_t freed_size = next_entry.block_size; + if (need_recalculate_virt_addr) { + /* We advanced more than by the block, so we need to calculate the actual advanced size. */ + const size_t block_size = impl.GetBlockSize(context.level, context.is_contiguous); + const KProcessAddress new_virt_addr = util::AlignDown(GetInteger(impl.GetAddressForContext(std::addressof(context))) + block_size, block_size); + MESOSPHERE_ABORT_UNLESS(new_virt_addr >= virt_addr + next_entry.block_size); + + freed_size = std::min(new_virt_addr - virt_addr, remaining_pages * PageSize); + } + + /* We can just advance by the block size. */ + virt_addr += freed_size; + remaining_pages -= freed_size / PageSize; + next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); } @@ -761,6 +462,126 @@ namespace ams::kern::arch::arm64 { R_SUCCEED(); } + Result KPageTable::Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); + MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); + + auto &impl = this->GetImpl(); + u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); + + /* Begin traversal. */ + TraversalContext context; + TraversalEntry entry; + bool valid = impl.BeginTraversal(std::addressof(entry), std::addressof(context), virt_addr); + + /* Iterate, mapping each page. */ + while (num_pages > 0) { + /* If we're mapping at the address, there must be nothing there. */ + MESOSPHERE_ABORT_UNLESS(!valid); + + /* If we fail, clean up any empty tables we may have allocated. */ + ON_RESULT_FAILURE { + /* Remove entries for and free any tables. */ + while (context.level < KPageTableImpl::EntryLevel_L1) { + /* If the higher-level table has entries, we don't need to do a free. */ + if (context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { + break; + } + + /* If there's no table, we also don't need to do a free. */ + const KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level]), PageSize)); + if (table == Null) { + break; + } + + /* Clear the entry for the table we're removing. */ + *context.level_entries[context.level + 1] = InvalidPageTableEntry; + + /* Remove the entry for the table one level higher. */ + if (context.level + 1 < KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 2]->CloseTableReferences(1); + } + + /* Advance our level. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + + /* Note that we performed an update and free the table. */ + this->NoteUpdated(); + this->FreePageTable(page_list, table); + } + }; + + /* If necessary, allocate page tables for the entry. */ + size_t mapping_size = entry.block_size; + while (mapping_size > page_size) { + /* Allocate the table. */ + const auto table = AllocatePageTable(page_list, reuse_ll); + R_UNLESS(table != Null, svc::ResultOutOfResource()); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + /* Update the block entry to be a table entry. */ + *context.level_entries[context.level] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(table), this->IsKernel(), true, 0); + + /* Add the entry to the table containing this one. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->OpenTableReferences(1); + } + + /* Decrease our level. */ + context.level = static_cast(util::ToUnderlying(context.level) - 1); + + /* Add our new entry to the context. */ + context.level_entries[context.level] = GetPointer(table) + impl.GetLevelIndex(virt_addr, context.level); + + /* Update our mapping size. */ + mapping_size = impl.GetBlockSize(context.level); + } + + /* Determine how many pages we can set up on this iteration. */ + const size_t block_size = impl.GetBlockSize(context.level); + const size_t max_ptes = (context.level == KPageTableImpl::EntryLevel_L1 ? impl.GetNumL1Entries() : BlocksPerTable) - ((reinterpret_cast(context.level_entries[context.level]) / sizeof(PageTableEntry)) & (BlocksPerTable - 1)); + const size_t max_pages = (block_size * max_ptes) / PageSize; + + const size_t cur_pages = std::min(max_pages, num_pages); + + /* Determine the new base attribute. */ + const bool contig = page_size >= BlocksPerContiguousBlock * mapping_size; + + const size_t num_ptes = cur_pages / (block_size / PageSize); + auto *pte = context.level_entries[context.level]; + for (size_t i = 0; i < num_ptes; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + i * block_size, entry_template, sw_reserved_bits, contig, context.level == KPageTableImpl::EntryLevel_L3); + sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); + } + + /* Add the entries to the table containing this one. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->OpenTableReferences(num_ptes); + } + + /* Update our context. */ + context.is_contiguous = contig; + context.level_entries[context.level] = pte + num_ptes - (contig ? BlocksPerContiguousBlock : 1); + + /* Advance our addresses. */ + phys_addr += cur_pages * PageSize; + virt_addr += cur_pages * PageSize; + num_pages -= cur_pages; + + /* Continue traversal. */ + valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); + } + + /* We mapped, so wait for our writes to take. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + R_SUCCEED(); + + } + Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); @@ -822,13 +643,7 @@ namespace ams::kern::arch::arm64 { } /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(orig_virt_addr + (num_pages - 1) * PageSize, page_list); - } - - /* Wait for pending stores to complete. */ - cpu::DataSynchronizationBarrierInnerShareableStore(); + this->MergePages(orig_virt_addr, num_pages, page_list); /* Open references to the pages, if we should. */ if (IsHeapPhysicalAddress(orig_phys_addr)) { @@ -920,336 +735,130 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(mapped_pages == num_pages); /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(orig_virt_addr + (num_pages - 1) * PageSize, page_list); - } - - /* Wait for pending stores to complete. */ - cpu::DataSynchronizationBarrierInnerShareableStore(); + this->MergePages(orig_virt_addr, num_pages, page_list); /* We succeeded! We want to persist the reference to the pages. */ spg.CancelClose(); R_SUCCEED(); } - bool KPageTable::MergePages(KProcessAddress virt_addr, PageLinkedList *page_list) { + bool KPageTable::MergePages(TraversalContext *context, PageLinkedList *page_list) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); + + /* Iteratively merge, until we can't. */ bool merged = false; - - /* If there's no L1 table, don't bother. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - if (!l1_entry->IsTable()) { - /* Ensure the table is not corrupted. */ - MESOSPHERE_ABORT_UNLESS(l1_entry->IsBlock() || l1_entry->IsEmpty()); - return merged; - } - - /* Examine and try to merge the L2 table. */ - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsTable()) { - /* We have an L3 entry. */ - L3PageTableEntry *l3_entry = impl.GetL3Entry(l2_entry, virt_addr); - if (!l3_entry->IsBlock()) { - return merged; + while (true) { + /* Try to merge. */ + KVirtualAddress freed_table = Null; + if (!impl.MergePages(std::addressof(freed_table), context, &KPageTable::NoteUpdatedCallback, this)) { + break; } - /* If it's not contiguous, try to make it so. */ - if (!l3_entry->IsContiguous()) { - virt_addr = util::AlignDown(GetInteger(virt_addr), L3ContiguousBlockSize); - const KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L3ContiguousBlockSize); - const u64 entry_template = l3_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - const L3PageTableEntry *check_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L3BlockSize * i) | PageTableEntry::Type_L3Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L3ContiguousBlockSize / L3BlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L3PageTableEntry *head_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * 0); - const L3PageTableEntry *tail_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * ((L3ContiguousBlockSize / L3BlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - *impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * i) = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + L3BlockSize * i, PageTableEntry(entry_template), sw_reserved_bits, true); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; + /* Free the page. */ + if (freed_table != Null) { + ClearPageTable(freed_table); + this->FreePageTable(page_list, freed_table); } - /* We might be able to upgrade a contiguous set of L3 entries into an L2 block. */ - virt_addr = util::AlignDown(GetInteger(virt_addr), L2BlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L2BlockSize); - const u64 entry_template = l3_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L2BlockSize / L3ContiguousBlockSize; i++) { - const L3PageTableEntry *check_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L3ContiguousBlockSize * i) | PageTableEntry::ContigType_Contiguous | PageTableEntry::Type_L3Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L2BlockSize / L3ContiguousBlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L3PageTableEntry *head_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * 0); - const L3PageTableEntry *tail_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * ((L2BlockSize / L3ContiguousBlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - *l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - - /* Note that we updated. */ - this->NoteUpdated(); + /* We performed at least one merge. */ merged = true; - - /* Free the L3 table. */ - KVirtualAddress l3_table = util::AlignDown(reinterpret_cast(l3_entry), PageSize); - if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) { - this->GetPageTableManager().Close(l3_table, L2BlockSize / L3BlockSize); - ClearPageTable(l3_table); - this->FreePageTable(page_list, l3_table); - } - } - - /* If the l2 entry is not a block or we can't make it contiguous, we're done. */ - if (!l2_entry->IsBlock()) { - return merged; - } - - /* If it's not contiguous, try to make it so. */ - if (!l2_entry->IsContiguous()) { - virt_addr = util::AlignDown(GetInteger(virt_addr), L2ContiguousBlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L2ContiguousBlockSize); - const u64 entry_template = l2_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - const L2PageTableEntry *check_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L2BlockSize * i) | PageTableEntry::Type_L2Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L2ContiguousBlockSize / L2BlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L2PageTableEntry *head_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * 0); - const L2PageTableEntry *tail_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * ((L2ContiguousBlockSize / L2BlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - *impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * i) = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + L2BlockSize * i, PageTableEntry(entry_template), sw_reserved_bits, true); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - } - - /* We might be able to upgrade a contiguous set of L2 entries into an L1 block. */ - virt_addr = util::AlignDown(GetInteger(virt_addr), L1BlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L1BlockSize); - const u64 entry_template = l2_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L1BlockSize / L2ContiguousBlockSize; i++) { - const L2PageTableEntry *check_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L2ContiguousBlockSize * i) | PageTableEntry::ContigType_Contiguous | PageTableEntry::Type_L2Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L1ContiguousBlockSize / L2ContiguousBlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L2PageTableEntry *head_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * 0); - const L2PageTableEntry *tail_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * ((L1BlockSize / L2ContiguousBlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - - /* Free the L2 table. */ - KVirtualAddress l2_table = util::AlignDown(reinterpret_cast(l2_entry), PageSize); - if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) { - this->GetPageTableManager().Close(l2_table, L1BlockSize / L2BlockSize); - ClearPageTable(l2_table); - this->FreePageTable(page_list, l2_table); } return merged; } - Result KPageTable::SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + void KPageTable::MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); - /* First, try to separate an L1 block into contiguous L2 blocks. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { - /* If our block size is too big, don't bother. */ - R_SUCCEED_IF(block_size >= L1BlockSize); + /* Begin traversal. */ + TraversalContext context; + TraversalEntry entry; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(context), virt_addr)); - /* Get the addresses we're working with. */ - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L1BlockSize); - const KPhysicalAddress block_phys_addr = l1_entry->GetBlock(); + /* Merge start of the range. */ + this->MergePages(std::addressof(context), page_list); - /* Allocate a new page for the L2 table. */ - const KVirtualAddress l2_table = this->AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_table != Null, svc::ResultOutOfResource()); - const KPhysicalAddress l2_phys = GetPageTablePhysicalAddress(l2_table); + /* If we have more than one page, do the same for the end of the range. */ + if (num_pages > 1) { + /* Begin traversal for end of range. */ + const size_t size = num_pages * PageSize; + const auto end_page = virt_addr + size; + const auto last_page = end_page - PageSize; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(context), last_page)); - /* Set the entries in the L2 table. */ - for (size_t i = 0; i < L1BlockSize / L2BlockSize; i++) { - const u64 entry_template = l1_entry->GetEntryTemplateForL2Block(i); - *(impl.GetL2EntryFromTable(l2_table, block_virt_addr + L2BlockSize * i)) = L2PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L2BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, true); + /* Merge. */ + this->MergePages(std::addressof(context), page_list); + } + } + + Result KPageTable::SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + auto &impl = this->GetImpl(); + + /* If at any point we fail, we want to merge. */ + ON_RESULT_FAILURE { this->MergePages(context, page_list); }; + + /* Iterate, separating until our block size is small enough. */ + while (entry->block_size > block_size) { + /* If necessary, allocate a table. */ + KVirtualAddress table = Null; + if (!context->is_contiguous) { + table = this->AllocatePageTable(page_list, reuse_ll); + R_UNLESS(table != Null, svc::ResultOutOfResource()); } - /* Open references to the L2 table. */ - this->GetPageTableManager().Open(l2_table, L1BlockSize / L2BlockSize); - - /* Replace the L1 entry with one to the new table. */ - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); - this->NoteUpdated(); + /* Separate. */ + impl.SeparatePages(entry, context, virt_addr, GetPointer(table), &KPageTable::NoteUpdatedCallback, this); } - /* If we don't have an l1 table, we're done. */ - MESOSPHERE_ABORT_UNLESS(l1_entry->IsTable() || l1_entry->IsEmpty()); - R_SUCCEED_IF(!l1_entry->IsTable()); - - /* We want to separate L2 contiguous blocks into L2 blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L2ContiguousBlockSize); - - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { - /* If we're contiguous, try to separate. */ - if (l2_entry->IsContiguous()) { - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L2ContiguousBlockSize); - const KPhysicalAddress block_phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L2ContiguousBlockSize); - - /* Mark the entries as non-contiguous. */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - L2PageTableEntry *target = impl.GetL2Entry(l1_entry, block_virt_addr + L2BlockSize * i); - const u64 entry_template = target->GetEntryTemplateForL2Block(i); - *target = L2PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L2BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, false); - } - this->NoteUpdated(); - } - - /* We want to separate L2 blocks into L3 contiguous blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L2BlockSize); - - /* Get the addresses we're working with. */ - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L2BlockSize); - const KPhysicalAddress block_phys_addr = l2_entry->GetBlock(); - - /* Allocate a new page for the L3 table. */ - const KVirtualAddress l3_table = this->AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l3_table != Null, svc::ResultOutOfResource()); - const KPhysicalAddress l3_phys = GetPageTablePhysicalAddress(l3_table); - - /* Set the entries in the L3 table. */ - for (size_t i = 0; i < L2BlockSize / L3BlockSize; i++) { - const u64 entry_template = l2_entry->GetEntryTemplateForL3Block(i); - *(impl.GetL3EntryFromTable(l3_table, block_virt_addr + L3BlockSize * i)) = L3PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L3BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, true); - } - - /* Open references to the L3 table. */ - this->GetPageTableManager().Open(l3_table, L2BlockSize / L3BlockSize); - - /* Replace the L2 entry with one to the new table. */ - PteDataMemoryBarrier(); - *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, l3_phys, this->IsKernel(), true); - this->NoteUpdated(); - } - - /* If we don't have an L3 table, we're done. */ - MESOSPHERE_ABORT_UNLESS(l2_entry->IsTable() || l2_entry->IsEmpty()); - R_SUCCEED_IF(!l2_entry->IsTable()); - - /* We want to separate L3 contiguous blocks into L2 blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L3ContiguousBlockSize); - - /* If we're contiguous, try to separate. */ - L3PageTableEntry *l3_entry = impl.GetL3Entry(l2_entry, virt_addr); - if (l3_entry->IsBlock() && l3_entry->IsContiguous()) { - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L3ContiguousBlockSize); - const KPhysicalAddress block_phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L3ContiguousBlockSize); - - /* Mark the entries as non-contiguous. */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - L3PageTableEntry *target = impl.GetL3Entry(l2_entry, block_virt_addr + L3BlockSize * i); - const u64 entry_template = target->GetEntryTemplateForL3Block(i); - *target = L3PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L3BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, false); - } - this->NoteUpdated(); - } - - /* We're done! */ R_SUCCEED(); } - Result KPageTable::SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + Result KPageTable::SeparatePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - /* If we fail while separating, re-merge. */ - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; + auto &impl = this->GetImpl(); - /* Try to separate pages. */ - R_RETURN(this->SeparatePagesImpl(virt_addr, block_size, page_list, reuse_ll)); + /* Begin traversal. */ + TraversalContext start_context; + TraversalEntry entry; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(start_context), virt_addr)); + + /* Separate pages at the start of the range. */ + const size_t size = num_pages * PageSize; + R_TRY(this->SeparatePagesImpl(std::addressof(entry), std::addressof(start_context), virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); + + /* If necessary, separate pages at the end of the range. */ + if (num_pages > 1) { + const auto end_page = virt_addr + size; + const auto last_page = end_page - PageSize; + + /* Begin traversal. */ + TraversalContext end_context; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(end_context), last_page)); + + + ON_RESULT_FAILURE { this->MergePages(std::addressof(start_context), page_list); }; + + R_TRY(this->SeparatePagesImpl(std::addressof(entry), std::addressof(end_context), last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); + } + + R_SUCCEED(); } Result KPageTable::ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* Ensure there are no pending data writes. */ + cpu::DataSynchronizationBarrier(); + /* Separate pages before we change permissions. */ - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } + R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); /* ===================================================== */ @@ -1338,59 +947,15 @@ namespace ams::kern::arch::arm64 { } /* Apply the entry template. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_virt_addr); - switch (next_entry.block_size) { - case L1BlockSize: - { - /* Write the updated entry. */ - *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr, entry_template, sw_reserved_bits, false); - } - break; - case L2ContiguousBlockSize: - case L2BlockSize: - { - /* Get the number of L2 blocks. */ - const size_t num_l2_blocks = next_entry.block_size / L2BlockSize; + { + const size_t num_entries = context.is_contiguous ? BlocksPerContiguousBlock : 1; - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - - /* Write the updated entry. */ - const bool contig = next_entry.block_size == L2ContiguousBlockSize; - for (size_t i = 0; i < num_l2_blocks; i++) { - *impl.GetL2EntryFromTable(l2_virt, cur_virt_addr + L2BlockSize * i) = L2PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + L2BlockSize * i, entry_template, sw_reserved_bits, contig); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - } - break; - case L3ContiguousBlockSize: - case L3BlockSize: - { - /* Get the number of L3 blocks. */ - const size_t num_l3_blocks = next_entry.block_size / L3BlockSize; - - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, cur_virt_addr); - - /* Get the L3 entry. */ - KPhysicalAddress l3_phys = Null; - MESOSPHERE_ABORT_UNLESS(l2_entry->GetTable(l3_phys)); - const KVirtualAddress l3_virt = GetPageTableVirtualAddress(l3_phys); - - /* Write the updated entry. */ - const bool contig = next_entry.block_size == L3ContiguousBlockSize; - for (size_t i = 0; i < num_l3_blocks; i++) { - *impl.GetL3EntryFromTable(l3_virt, cur_virt_addr + L3BlockSize * i) = L3PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + L3BlockSize * i, entry_template, sw_reserved_bits, contig); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - } - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + auto * const pte = context.level_entries[context.level]; + const size_t block_size = impl.GetBlockSize(context.level); + for (size_t i = 0; i < num_entries; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + i * block_size, entry_template, sw_reserved_bits, context.is_contiguous, context.level == KPageTableImpl::EntryLevel_L3); + sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); + } } /* If our option asks us to, try to merge mappings. */ @@ -1400,7 +965,7 @@ namespace ams::kern::arch::arm64 { if (util::IsAligned(GetInteger(cur_virt_addr) + next_entry.block_size, larger_align)) { const uintptr_t aligned_start = util::AlignDown(GetInteger(cur_virt_addr), larger_align); if (orig_virt_addr <= aligned_start && aligned_start + larger_align - 1 < GetInteger(orig_virt_addr) + (num_pages * PageSize) - 1) { - merge = this->MergePages(cur_virt_addr, page_list); + merge = this->MergePages(std::addressof(context), page_list); } else { merge = false; } @@ -1411,7 +976,7 @@ namespace ams::kern::arch::arm64 { /* If we merged, correct the traversal to a sane state. */ if (merge) { - /* NOTE: Nintendo does not verify the result of this BeginTraversal call. */ + /* NOTE: Begin a new traversal, now that we've merged. */ MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), cur_virt_addr)); /* The actual size needs to not take into account the portion of the block before our virtual address. */ @@ -1456,13 +1021,13 @@ namespace ams::kern::arch::arm64 { /* Finally, apply the changes as directed, flushing the mappings before they're applied (if we should). */ ApplyEntryTemplate(entry_template, flush_mapping ? ApplyOption_FlushDataCache : ApplyOption_None); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); } /* We've succeeded, now perform what coalescing we can. */ - this->MergePages(virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(virt_addr + (num_pages - 1) * PageSize, page_list); - } + this->MergePages(virt_addr, num_pages, page_list); R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 280498f78..5ce64e3f6 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -21,6 +21,59 @@ namespace ams::kern::arch::arm64 { m_table = static_cast(tb); m_is_kernel = true; m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize; + + /* Page table entries created by KInitialPageTable need to be iterated and modified to ensure KPageTable invariants. */ + PageTableEntry *level_entries[EntryLevel_Count] = { nullptr, nullptr, m_table }; + u32 level = EntryLevel_L1; + while (level != EntryLevel_L1 || (level_entries[EntryLevel_L1] - static_cast(m_table)) < m_num_entries) { + /* Get the pte; it must never have the validity-extension flag set. */ + auto *pte = level_entries[level]; + MESOSPHERE_ASSERT((pte->GetSoftwareReservedBits() & PageTableEntry::SoftwareReservedBit_Valid) == 0); + + /* While we're a table, recurse, fixing up the reference counts. */ + while (level > EntryLevel_L3 && pte->IsMappedTable()) { + /* Count how many references are in the table. */ + auto *table = GetPointer(GetPageTableVirtualAddress(pte->GetTable())); + + size_t ref_count = 0; + for (size_t i = 0; i < BlocksPerTable; ++i) { + if (table[i].IsMapped()) { + ++ref_count; + } + } + + /* Set the reference count for our new page, adding one additional uncloseable reference; kernel pages must never be unreferenced. */ + pte->SetTableReferenceCount(ref_count + 1).SetValid(); + + /* Iterate downwards. */ + level -= 1; + level_entries[level] = table; + pte = level_entries[level]; + + /* Check that the entry isn't unexpected. */ + MESOSPHERE_ASSERT((pte->GetSoftwareReservedBits() & PageTableEntry::SoftwareReservedBit_Valid) == 0); + } + + /* We're dealing with some block. If it's mapped, set it valid. */ + if (pte->IsMapped()) { + pte->SetValid(); + } + + /* Advance. */ + while (true) { + /* Advance to the next entry at the current level. */ + if (!util::IsAligned(reinterpret_cast(++level_entries[level]), PageSize)) { + break; + } + + /* If we're at the end of a level, advance upwards. */ + level_entries[level++] = nullptr; + + if (level > EntryLevel_L1) { + return; + } + } + } } void KPageTableImpl::InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end) { @@ -33,103 +86,10 @@ namespace ams::kern::arch::arm64 { return m_table; } - bool KPageTableImpl::ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const { - /* Set the L3 entry. */ - out_context->l3_entry = l3_entry; - - if (l3_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l3_entry->GetBlock() + (virt_addr & (L3BlockSize - 1)); - if (l3_entry->IsContiguous()) { - out_entry->block_size = L3ContiguousBlockSize; - } else { - out_entry->block_size = L3BlockSize; - } - out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits(); - out_entry->attr = 0; - - return true; - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L3BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - return false; - } - } - - bool KPageTableImpl::ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const { - /* Set the L2 entry. */ - out_context->l2_entry = l2_entry; - - if (l2_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l2_entry->GetBlock() + (virt_addr & (L2BlockSize - 1)); - if (l2_entry->IsContiguous()) { - out_entry->block_size = L2ContiguousBlockSize; - } else { - out_entry->block_size = L2BlockSize; - } - out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits(); - out_entry->attr = 0; - - /* Set the output context. */ - out_context->l3_entry = nullptr; - return true; - } else if (l2_entry->IsTable()) { - return this->ExtractL3Entry(out_entry, out_context, this->GetL3EntryFromTable(GetPageTableVirtualAddress(l2_entry->GetTable()), virt_addr), virt_addr); - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L2BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - - out_context->l3_entry = nullptr; - return false; - } - } - - bool KPageTableImpl::ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const { - /* Set the L1 entry. */ - out_context->l1_entry = l1_entry; - - if (l1_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l1_entry->GetBlock() + (virt_addr & (L1BlockSize - 1)); - if (l1_entry->IsContiguous()) { - out_entry->block_size = L1ContiguousBlockSize; - } else { - out_entry->block_size = L1BlockSize; - } - out_entry->sw_reserved_bits = l1_entry->GetSoftwareReservedBits(); - - /* Set the output context. */ - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; - return true; - } else if (l1_entry->IsTable()) { - return this->ExtractL2Entry(out_entry, out_context, this->GetL2EntryFromTable(GetPageTableVirtualAddress(l1_entry->GetTable()), virt_addr), virt_addr); - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; - return false; - } - } - bool KPageTableImpl::BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const { /* Setup invalid defaults. */ - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - out_context->l1_entry = m_table + m_num_entries; - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; + *out_entry = {}; + *out_context = {}; /* Validate that we can read the actual entry. */ const size_t l0_index = GetL0Index(address); @@ -146,125 +106,78 @@ namespace ams::kern::arch::arm64 { } } - /* Extract the entry. */ - const bool valid = this->ExtractL1Entry(out_entry, out_context, this->GetL1Entry(address), address); + /* Get the L1 entry, and check if it's a table. */ + out_context->level_entries[EntryLevel_L1] = this->GetL1Entry(address); + if (out_context->level_entries[EntryLevel_L1]->IsMappedTable()) { + /* Get the L2 entry, and check if it's a table. */ + out_context->level_entries[EntryLevel_L2] = this->GetL2EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L1]->GetTable()), address); + if (out_context->level_entries[EntryLevel_L2]->IsMappedTable()) { + /* Get the L3 entry. */ + out_context->level_entries[EntryLevel_L3] = this->GetL3EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L2]->GetTable()), address); - /* Update the context for next traversal. */ - switch (out_entry->block_size) { - case L1ContiguousBlockSize: - out_context->l1_entry += (L1ContiguousBlockSize / L1BlockSize) - GetContiguousL1Offset(address) / L1BlockSize; - break; - case L1BlockSize: - out_context->l1_entry += 1; - break; - case L2ContiguousBlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += (L2ContiguousBlockSize / L2BlockSize) - GetContiguousL2Offset(address) / L2BlockSize; - break; - case L2BlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - out_context->l3_entry += (L3ContiguousBlockSize / L3BlockSize) - GetContiguousL3Offset(address) / L3BlockSize; - break; - case L3BlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - out_context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + /* It's either a page or not. */ + out_context->level = EntryLevel_L3; + } else { + /* Not a L2 table, so possibly an L2 block. */ + out_context->level = EntryLevel_L2; + } + } else { + /* Not a L1 table, so possibly an L1 block. */ + out_context->level = EntryLevel_L1; } - return valid; + /* Determine other fields. */ + const auto *pte = out_context->level_entries[out_context->level]; + + out_context->is_contiguous = pte->IsContiguous(); + + out_entry->sw_reserved_bits = pte->GetSoftwareReservedBits(); + out_entry->attr = 0; + out_entry->phys_addr = this->GetBlock(pte, out_context->level) + this->GetOffset(address, out_context->level); + out_entry->block_size = static_cast(1) << (PageBits + LevelBits * out_context->level + 4 * out_context->is_contiguous); + + return out_context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); } bool KPageTableImpl::ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const { - bool valid = false; + /* Advance entry. */ + auto *cur_pte = context->level_entries[context->level]; + auto *next_pte = reinterpret_cast(context->is_contiguous ? util::AlignDown(reinterpret_cast(cur_pte), BlocksPerContiguousBlock * sizeof(PageTableEntry)) + BlocksPerContiguousBlock * sizeof(PageTableEntry) : reinterpret_cast(cur_pte) + sizeof(PageTableEntry)); - /* Check if we're not at the end of an L3 table. */ - if (!util::IsAligned(reinterpret_cast(context->l3_entry), PageSize)) { - valid = this->ExtractL3Entry(out_entry, context, context->l3_entry, Null); + /* Set the pte. */ + context->level_entries[context->level] = next_pte; - switch (out_entry->block_size) { - case L3ContiguousBlockSize: - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } else if (!util::IsAligned(reinterpret_cast(context->l2_entry), PageSize)) { - /* We're not at the end of an L2 table. */ - valid = this->ExtractL2Entry(out_entry, context, context->l2_entry, Null); + /* Advance appropriately. */ + while (context->level < EntryLevel_L1 && util::IsAligned(reinterpret_cast(context->level_entries[context->level]), PageSize)) { + /* Advance the above table by one entry. */ + context->level_entries[context->level + 1]++; + context->level = static_cast(util::ToUnderlying(context->level) + 1); + } - switch (out_entry->block_size) { - case L2ContiguousBlockSize: - context->l2_entry += (L2ContiguousBlockSize / L2BlockSize); - break; - case L2BlockSize: - context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - context->l2_entry += 1; - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l2_entry += 1; - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } else { - /* We need to update the l1 entry. */ - const size_t l1_index = context->l1_entry - m_table; - if (l1_index < m_num_entries) { - valid = this->ExtractL1Entry(out_entry, context, context->l1_entry, Null); - } else { - /* Invalid, end traversal. */ - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - context->l1_entry = m_table + m_num_entries; - context->l2_entry = nullptr; - context->l3_entry = nullptr; + /* Check if we've hit the end of the L1 table. */ + if (context->level == EntryLevel_L1) { + if (context->level_entries[EntryLevel_L1] - static_cast(m_table) >= m_num_entries) { + *context = {}; + *out_entry = {}; return false; } - - switch (out_entry->block_size) { - case L1ContiguousBlockSize: - context->l1_entry += (L1ContiguousBlockSize / L1BlockSize); - break; - case L1BlockSize: - context->l1_entry += 1; - break; - case L2ContiguousBlockSize: - context->l1_entry += 1; - context->l2_entry += (L2ContiguousBlockSize / L2BlockSize); - break; - case L2BlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } } - return valid; + /* We may have advanced to a new table, and if we have we should descend. */ + while (context->level > EntryLevel_L3 && context->level_entries[context->level]->IsMappedTable()) { + context->level_entries[context->level - 1] = GetPointer(GetPageTableVirtualAddress(context->level_entries[context->level]->GetTable())); + context->level = static_cast(util::ToUnderlying(context->level) - 1); + } + + const auto *pte = context->level_entries[context->level]; + + context->is_contiguous = pte->IsContiguous(); + + out_entry->sw_reserved_bits = pte->GetSoftwareReservedBits(); + out_entry->attr = 0; + out_entry->phys_addr = this->GetBlock(pte, context->level); + out_entry->block_size = static_cast(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous); + return context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); } bool KPageTableImpl::GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const { @@ -283,32 +196,147 @@ namespace ams::kern::arch::arm64 { } } - /* Try to get from l1 table. */ - const L1PageTableEntry *l1_entry = this->GetL1Entry(address); - if (l1_entry->IsBlock()) { - *out = l1_entry->GetBlock() + GetL1Offset(address); - return true; - } else if (!l1_entry->IsTable()) { - return false; + /* Get the L1 entry, and check if it's a table. */ + const PageTableEntry *pte = this->GetL1Entry(address); + EntryLevel level = EntryLevel_L1; + if (pte->IsMappedTable()) { + /* Get the L2 entry, and check if it's a table. */ + pte = this->GetL2EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address); + level = EntryLevel_L2; + if (pte->IsMappedTable()) { + pte = this->GetL3EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address); + level = EntryLevel_L3; + } } - /* Try to get from l2 table. */ - const L2PageTableEntry *l2_entry = this->GetL2Entry(l1_entry, address); - if (l2_entry->IsBlock()) { - *out = l2_entry->GetBlock() + GetL2Offset(address); - return true; - } else if (!l2_entry->IsTable()) { - return false; + const bool is_block = level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); + if (is_block) { + *out = this->GetBlock(pte, level) + this->GetOffset(address, level); + } else { + *out = Null; } - /* Try to get from l3 table. */ - const L3PageTableEntry *l3_entry = this->GetL3Entry(l2_entry, address); - if (l3_entry->IsBlock()) { - *out = l3_entry->GetBlock() + GetL3Offset(address); - return true; + return is_block; + } + + bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt) { + /* We want to upgrade the pages by one step. */ + if (context->is_contiguous) { + /* We can't merge an L1 table. */ + if (context->level == EntryLevel_L1) { + return false; + } + + /* We want to upgrade a contiguous mapping in a table to a block. */ + PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerTable * sizeof(PageTableEntry))); + const KPhysicalAddress phys_addr = util::AlignDown(GetBlock(pte, context->level), GetBlockSize(static_cast(context->level + 1), false)); + + /* First, check that all entries are valid for us to merge. */ + const u64 entry_template = pte->GetEntryTemplateForMerge(); + for (size_t i = 0; i < BlocksPerTable; ++i) { + if (!pte[i].IsForMerge(entry_template | GetInteger(phys_addr + (i << (PageBits + LevelBits * context->level))) | PageTableEntry::ContigType_Contiguous | pte->GetTestTableMask())) { + return false; + } + if (i > 0 && pte[i].IsHeadOrHeadAndBodyMergeDisabled()) { + return false; + } + if (i < BlocksPerTable - 1 && pte[i].IsTailMergeDisabled()) { + return false; + } + } + + /* The entries are valid for us to merge, so merge them. */ + const auto *head_pte = pte; + const auto *tail_pte = pte + BlocksPerTable - 1; + const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled()); + + *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false, false); + on_entry_updated(pt); + + /* Update our context. */ + context->is_contiguous = false; + context->level = static_cast(util::ToUnderlying(context->level) + 1); + + /* Set the output to the table we just freed. */ + *out = KVirtualAddress(pte); + } else { + /* We want to upgrade a non-contiguous mapping to a contiguous mapping. */ + PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerContiguousBlock * sizeof(PageTableEntry))); + const KPhysicalAddress phys_addr = util::AlignDown(GetBlock(pte, context->level), GetBlockSize(context->level, true)); + + /* First, check that all entries are valid for us to merge. */ + const u64 entry_template = pte->GetEntryTemplateForMerge(); + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + if (!pte[i].IsForMerge(entry_template | GetInteger(phys_addr + (i << (PageBits + LevelBits * context->level))) | pte->GetTestTableMask())) { + return false; + } + if (i > 0 && pte[i].IsHeadOrHeadAndBodyMergeDisabled()) { + return false; + } + if (i < BlocksPerContiguousBlock - 1 && pte[i].IsTailMergeDisabled()) { + return false; + } + } + + /* The entries are valid for us to merge, so merge them. */ + const auto *head_pte = pte; + const auto *tail_pte = pte + BlocksPerContiguousBlock - 1; + const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled()); + + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + (i << (PageBits + LevelBits * context->level)), PageTableEntry(entry_template), sw_reserved_bits, true, context->level == EntryLevel_L3); + } + on_entry_updated(pt); + + /* Update our context. */ + context->level_entries[context->level] = pte; + context->is_contiguous = true; } - return false; + return true; + } + + void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const { + /* We want to downgrade the pages by one step. */ + if (context->is_contiguous) { + /* We want to downgrade a contiguous mapping to a non-contiguous mapping. */ + pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerContiguousBlock * sizeof(PageTableEntry))); + + auto * const first = pte; + const KPhysicalAddress block = this->GetBlock(first, context->level); + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * context->level)), PageTableEntry(first->GetEntryTemplateForSeparateContiguous(i)), PageTableEntry::SeparateContiguousTag{}); + } + on_entry_updated(pt); + + context->is_contiguous = false; + + context->level_entries[context->level] = pte + (this->GetLevelIndex(address, context->level) & (BlocksPerContiguousBlock - 1)); + } else { + /* We want to downgrade a block into a table. */ + auto * const first = context->level_entries[context->level]; + const KPhysicalAddress block = this->GetBlock(first, context->level); + for (size_t i = 0; i < BlocksPerTable; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * (context->level - 1))), PageTableEntry(first->GetEntryTemplateForSeparate(i)), PageTableEntry::SoftwareReservedBit_None, true, context->level - 1 == EntryLevel_L3); + } + + context->is_contiguous = true; + context->level = static_cast(util::ToUnderlying(context->level) - 1); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + /* Update the block entry to be a table entry. */ + *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(pte)), m_is_kernel, true, BlocksPerTable); + on_entry_updated(pt); + + context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level); + } + + entry->sw_reserved_bits = context->level_entries[context->level]->GetSoftwareReservedBits(); + entry->attr = 0; + entry->phys_addr = this->GetBlock(context->level_entries[context->level], context->level) + this->GetOffset(address, context->level); + entry->block_size = static_cast(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous); } void KPageTableImpl::Dump(uintptr_t start, size_t size) const { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp index b3cef6755..76e91cff7 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -21,6 +21,15 @@ namespace ams::kern::arch::arm64 { void UserModeThreadStarter(); void SupervisorModeThreadStarter(); + void InvokeSupervisorModeThread(uintptr_t argument, uintptr_t entrypoint) { + /* Invoke the function. */ + using SupervisorModeFunctionType = void (*)(uintptr_t); + reinterpret_cast(entrypoint)(argument); + + /* Wait forever. */ + AMS_INFINITE_LOOP(); + } + void OnThreadStart() { MESOSPHERE_ASSERT(!KInterruptManager::AreInterruptsEnabled()); /* Send KDebug event for this thread's creation. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s index 5b1fd4a51..1d9d2c5da 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s @@ -24,12 +24,12 @@ _ZN3ams4kern4arch5arm6432UserspaceAccessFunctionAreaBeginEv: /* ================ All Userspace Access Functions after this line. ================ */ -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -48,12 +48,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -72,7 +72,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -87,12 +87,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -111,7 +111,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -126,12 +126,26 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv: + /* Just load and store a u64. */ + ldtr x2, [x1] + str x2, [x0] + + /* We're done. */ + mov x0, #1 + ret + +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, %function +.balign 0x10 +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv: /* Just load and store a u32. */ ldtr w2, [x1] str w2, [x0] @@ -140,12 +154,27 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv: + /* Just load and store a u32. */ + /* NOTE: This is done with supervisor access permissions. */ + ldr w2, [x1] + str w2, [x0] + + /* We're done. */ + mov x0, #1 + ret + +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, %function +.balign 0x10 +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -175,12 +204,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm: mov x0, #0 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -199,12 +228,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -223,7 +252,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -238,12 +267,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -262,7 +291,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -277,12 +306,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv: /* Just load and store a u32. */ ldr w2, [x1] sttr w2, [x0] @@ -291,12 +320,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyStringToUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -326,114 +355,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm: mov x0, #0 ret -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemory(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm: - /* Check if there's anything to clear. */ - cmp x1, #0 - b.eq 2f - - /* Keep track of the last address. */ - add x2, x0, x1 - -1: /* We're copying memory byte-by-byte. */ - sttrb wzr, [x0] - add x0, x0, #1 - cmp x0, x2 - b.ne 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned32Bit(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm: - /* Check if there are 0x40 bytes to clear. */ - cmp x1, #0x3F - b.ls 2f - sttr xzr, [x0, #0x00] - sttr xzr, [x0, #0x08] - sttr xzr, [x0, #0x10] - sttr xzr, [x0, #0x18] - sttr xzr, [x0, #0x20] - sttr xzr, [x0, #0x28] - sttr xzr, [x0, #0x30] - sttr xzr, [x0, #0x38] - add x0, x0, #0x40 - sub x1, x1, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm - -1: /* We have less than 0x40 bytes to clear. */ - cmp x1, #0 - b.eq 2f - sttr wzr, [x0] - add x0, x0, #4 - sub x1, x1, #4 - b 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned64Bit(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm: - /* Check if there are 0x40 bytes to clear. */ - cmp x1, #0x3F - b.ls 2f - sttr xzr, [x0, #0x00] - sttr xzr, [x0, #0x08] - sttr xzr, [x0, #0x10] - sttr xzr, [x0, #0x18] - sttr xzr, [x0, #0x20] - sttr xzr, [x0, #0x28] - sttr xzr, [x0, #0x30] - sttr xzr, [x0, #0x38] - add x0, x0, #0x40 - sub x1, x1, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm - -1: /* We have less than 0x40 bytes to clear. */ - cmp x1, #0 - b.eq 2f - sttr xzr, [x0] - add x0, x0, #8 - sub x1, x1, #8 - b 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemorySize32Bit(void *dst) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv: - /* Just store a zero. */ - sttr wzr, [x0] - - /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj: /* Load the value from the address. */ ldaxr w4, [x1] @@ -448,7 +375,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: stlxr w6, w5, [x1] /* If we failed to store, try again. */ - cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj + cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj /* We're done. */ str w4, [x0] @@ -456,12 +383,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: ret -/* ams::kern::arch::arm64::UserspaceAccess::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii -.type _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii: /* Load the value from the address. */ ldaxr w4, [x1] @@ -479,19 +406,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii: stlxr w5, w3, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii 2: /* We're done. */ str w4, [x0] mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i -.type _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i: /* Load the value from the address. */ ldaxr w3, [x1] @@ -510,19 +437,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i: stlxr w5, w4, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i 2: /* We're done. */ str w3, [x0] mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::StoreDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::StoreDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -537,12 +464,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::FlushDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::FlushDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -557,12 +484,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::InvalidateDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::InvalidateDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -577,12 +504,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -627,12 +554,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -677,12 +604,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -727,12 +654,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -772,12 +699,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -817,12 +744,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s new file mode 100644 index 000000000..f82db4454 --- /dev/null +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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 . + */ + +/* ams::kern::svc::CallWaitForAddress64From32() */ +.section .text._ZN3ams4kern3svc26CallWaitForAddress64From32Ev, "ax", %progbits +.global _ZN3ams4kern3svc26CallWaitForAddress64From32Ev +.type _ZN3ams4kern3svc26CallWaitForAddress64From32Ev, %function +_ZN3ams4kern3svc26CallWaitForAddress64From32Ev: + /* Save LR + callee-save registers. */ + str x30, [sp, #-16]! + stp x6, x7, [sp, #-16]! + + /* Gather the arguments into correct registers. */ + /* NOTE: This has to be manually implemented via asm, */ + /* in order to avoid breaking ABI with pre-19.0.0. */ + orr x2, x2, x5, lsl#32 + orr x3, x3, x4, lsl#32 + + /* Invoke the svc handler. */ + bl _ZN3ams4kern3svc22WaitForAddress64From32ENS_3svc7AddressENS2_15ArbitrationTypeEll + + /* Clean up registers. */ + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + mov x5, xzr + + ldp x6, x7, [sp], #0x10 + ldr x30, [sp], #0x10 + ret + +/* ams::kern::svc::CallWaitForAddress64() */ +.section .text._ZN3ams4kern3svc20CallWaitForAddress64Ev, "ax", %progbits +.global _ZN3ams4kern3svc20CallWaitForAddress64Ev +.type _ZN3ams4kern3svc20CallWaitForAddress64Ev, %function +_ZN3ams4kern3svc20CallWaitForAddress64Ev: + /* Save LR + FP. */ + stp x29, x30, [sp, #-16]! + + /* Invoke the svc handler. */ + bl _ZN3ams4kern3svc22WaitForAddress64From32ENS_3svc7AddressENS2_15ArbitrationTypeEll + + /* Clean up registers. */ + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + mov x5, xzr + mov x6, xzr + mov x7, xzr + + ldp x29, x30, [sp], #0x10 + ret diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp index cb9151823..cfc0cb7c5 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp @@ -36,6 +36,10 @@ namespace ams::kern::svc { /* Declare special prototype for (unsupported) CallCallSecureMonitor64From32. */ void CallCallSecureMonitor64From32(); + /* Declare special prototypes for WaitForAddress. */ + void CallWaitForAddress64(); + void CallWaitForAddress64From32(); + namespace { #ifndef MESOSPHERE_USE_STUBBED_SVC_TABLES @@ -81,6 +85,8 @@ namespace ams::kern::svc { table[svc::SvcId_CallSecureMonitor] = CallCallSecureMonitor64From32; + table[svc::SvcId_WaitForAddress] = CallWaitForAddress64From32; + return table; }(); @@ -97,6 +103,8 @@ namespace ams::kern::svc { table[svc::SvcId_ReturnFromException] = CallReturnFromException64; + table[svc::SvcId_WaitForAddress] = CallWaitForAddress64; + return table; }(); diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp index f70bcbb97..292c25750 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp @@ -1214,7 +1214,7 @@ namespace ams::kern::board::nintendo::nx { for (size_t i = 0; i < map_count; ++i) { /* Get the physical address. */ const KPhysicalAddress phys_addr = l2[l2_index + i].GetPhysicalAddress(); - MESOSPHERE_ASSERT(IsHeapPhysicalAddress(phys_addr)); + MESOSPHERE_ASSERT(phys_addr == Null || IsHeapPhysicalAddress(phys_addr)); /* Fully invalidate the entry. */ l2[l2_index + i].Invalidate(); diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp index bb782d390..5e5983c86 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp @@ -31,7 +31,6 @@ namespace ams::kern::board::nintendo::nx { /* Struct representing registers saved on wake/sleep. */ class SavedSystemRegisters { private: - u64 ttbr0_el1; u64 elr_el1; u64 sp_el0; u64 spsr_el1; @@ -90,7 +89,6 @@ namespace ams::kern::board::nintendo::nx { void SavedSystemRegisters::Save() { /* Save system registers. */ - this->ttbr0_el1 = cpu::GetTtbr0El1(); this->tpidr_el0 = cpu::GetTpidrEl0(); this->elr_el1 = cpu::GetElrEl1(); this->sp_el0 = cpu::GetSpEl0(); @@ -405,7 +403,7 @@ namespace ams::kern::board::nintendo::nx { cpu::EnsureInstructionConsistency(); /* Restore system registers. */ - cpu::SetTtbr0El1 (this->ttbr0_el1); + cpu::SetTtbr0El1 (KPageTable::GetKernelTtbr0()); cpu::SetTpidrEl0 (this->tpidr_el0); cpu::SetElrEl1 (this->elr_el1); cpu::SetSpEl0 (this->sp_el0); diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 52a894d1c..58e86f152 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -26,7 +26,7 @@ namespace ams::kern::board::nintendo::nx { constexpr size_t SecureSizeMax = util::AlignDown(512_MB - 1, SecureAlignment); /* Global variables for panic. */ - constinit bool g_call_smc_on_panic; + constinit const volatile bool g_call_smc_on_panic = false; /* Global variables for secure memory. */ constinit KSpinLock g_secure_applet_lock; @@ -361,7 +361,9 @@ namespace ams::kern::board::nintendo::nx { }(); /* Return (possibly) adjusted size. */ - constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB; + /* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */ + /* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */ + const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB; return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; } @@ -401,34 +403,67 @@ namespace ams::kern::board::nintendo::nx { } /* System Initialization. */ - void KSystemControl::InitializePhase1() { + void KSystemControl::ConfigureKTargetSystem() { /* Configure KTargetSystem. */ + volatile auto *ts = const_cast(std::addressof(KTargetSystem::s_data)); { - /* Set IsDebugMode. */ + /* Set whether we're in debug mode. */ { - KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode)); + ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode); - /* If debug mode, we want to initialize uart logging. */ - KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode()); + /* If we're not in debug mode, we don't want to initialize uart logging. */ + ts->disable_debug_logging = ts->is_not_debug_mode; } /* Set Kernel Configuration. */ { const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; - KTargetSystem::EnableDebugMemoryFill(kernel_config.Get()); - KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get()); - KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get()); - KTargetSystem::EnableUserPmuAccess(kernel_config.Get()); + ts->disable_debug_memory_fill = !kernel_config.Get(); + ts->disable_user_exception_handlers = !kernel_config.Get(); + ts->disable_dynamic_resource_limits = kernel_config.Get(); + ts->disable_user_pmu_access = !kernel_config.Get(); - g_call_smc_on_panic = kernel_config.Get(); + /* Configure call smc on panic. */ + *const_cast(std::addressof(g_call_smc_on_panic)) = kernel_config.Get(); } /* Set Kernel Debugging. */ { /* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */ /* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */ - KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification)); + ts->disable_kernel_debugging = !GetConfigBool(smc::ConfigItem::DisableProgramVerification); + } + } + } + + void KSystemControl::InitializePhase1() { + /* Enable KTargetSystem. */ + KTargetSystem::SetInitialized(); + + /* Check KTargetSystem was configured correctly. */ + { + /* Check IsDebugMode. */ + { + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugMode() == GetConfigBool(smc::ConfigItem::IsDebugMode)); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugLoggingEnabled() == GetConfigBool(smc::ConfigItem::IsDebugMode)); + } + + /* Check Kernel Configuration. */ + { + const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; + + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugMemoryFillEnabled() == kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserExceptionHandlersEnabled() == kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled() == !kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserPmuAccessEnabled() == kernel_config.Get()); + + MESOSPHERE_ABORT_UNLESS(g_call_smc_on_panic == kernel_config.Get()); + } + + /* Check Kernel Debugging. */ + { + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsKernelDebuggingEnabled() == GetConfigBool(smc::ConfigItem::DisableProgramVerification)); } } @@ -491,7 +526,7 @@ namespace ams::kern::board::nintendo::nx { KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(s_initialized_random_generator)) { + if (AMS_LIKELY(!s_uninitialized_random_generator)) { return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); } else { return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc); @@ -502,7 +537,7 @@ namespace ams::kern::board::nintendo::nx { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(s_initialized_random_generator)) { + if (AMS_LIKELY(!s_uninitialized_random_generator)) { return s_random_generator.GenerateRandomU64(); } else { return GenerateRandomU64FromSmc(); @@ -590,13 +625,8 @@ namespace ams::kern::board::nintendo::nx { for (size_t i = 0; i < RebootPayloadSize / sizeof(u32); ++i) { GetPointer(iram_address)[i] = GetPointer(reboot_payload)[i]; } - - /* Reboot. */ - smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToPayload); - } else { - /* If we don't have a payload, reboot to rcm. */ - smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm); } + smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToFatalError); } if (g_call_smc_on_panic) { diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index 1e64d11f9..6ee325aa3 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -98,9 +98,10 @@ namespace ams::kern::board::nintendo::nx::smc { }; enum UserRebootType { - UserRebootType_None = 0, - UserRebootType_ToRcm = 1, - UserRebootType_ToPayload = 2, + UserRebootType_None = 0, + UserRebootType_ToRcm = 1, + UserRebootType_ToPayload = 2, + UserRebootType_ToFatalError = 3, }; void GenerateRandomBytes(void *dst, size_t size); diff --git a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp index c084c9053..66c0c1645 100644 --- a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp +++ b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp @@ -23,6 +23,10 @@ namespace ams::kern { return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address)); } + ALWAYS_INLINE bool ReadFromUser(s64 *out, KProcessAddress address) { + return UserspaceAccess::CopyMemoryFromUserSize64Bit(out, GetVoidPointer(address)); + } + ALWAYS_INLINE bool DecrementIfLessThan(s32 *out, KProcessAddress address, s32 value) { /* NOTE: If scheduler lock is not held here, interrupt disable is required. */ /* KScopedInterruptDisable di; */ @@ -279,4 +283,51 @@ namespace ams::kern { R_RETURN(cur_thread->GetWaitResult()); } + Result KAddressArbiter::WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout) { + /* Prepare to wait. */ + KThread *cur_thread = GetCurrentThreadPointer(); + KHardwareTimer *timer; + ThreadQueueImplForKAddressArbiter wait_queue(std::addressof(m_tree)); + + { + KScopedSchedulerLockAndSleep slp(std::addressof(timer), cur_thread, timeout); + + /* Check that the thread isn't terminating. */ + if (cur_thread->IsTerminationRequested()) { + slp.CancelSleep(); + R_THROW(svc::ResultTerminationRequested()); + } + + /* Read the value from userspace. */ + s64 user_value; + if (!ReadFromUser(std::addressof(user_value), addr)) { + slp.CancelSleep(); + R_THROW(svc::ResultInvalidCurrentMemory()); + } + + /* Check that the value is equal. */ + if (value != user_value) { + slp.CancelSleep(); + R_THROW(svc::ResultInvalidState()); + } + + /* Check that the timeout is non-zero. */ + if (timeout == 0) { + slp.CancelSleep(); + R_THROW(svc::ResultTimedOut()); + } + + /* Set the arbiter. */ + cur_thread->SetAddressArbiter(std::addressof(m_tree), addr); + m_tree.insert(*cur_thread); + + /* Wait for the thread to finish. */ + wait_queue.SetHardwareTimer(timer); + cur_thread->BeginWait(std::addressof(wait_queue)); + } + + /* Get the wait result. */ + R_RETURN(cur_thread->GetWaitResult()); + } + } diff --git a/libraries/libmesosphere/source/kern_k_address_space_info.cpp b/libraries/libmesosphere/source/kern_k_address_space_info.cpp index ef585eba8..3aa24c5de 100644 --- a/libraries/libmesosphere/source/kern_k_address_space_info.cpp +++ b/libraries/libmesosphere/source/kern_k_address_space_info.cpp @@ -37,6 +37,24 @@ namespace ams::kern { { 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, }, }; + constexpr u8 FlagsToAddressSpaceWidthTable[4] = { + 32, 36, 32, 39 + }; + + constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag flags) { + /* Convert the input flags to an array index. */ + const size_t idx = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask) >> ams::svc::CreateProcessFlag_AddressSpaceShift; + MESOSPHERE_ABORT_UNLESS(idx < sizeof(FlagsToAddressSpaceWidthTable)); + + /* Return the width. */ + return FlagsToAddressSpaceWidthTable[idx]; + } + + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32Bit) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated) == 36); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64Bit) == 39); + KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) { for (auto &info : AddressSpaceInfos) { if (info.GetWidth() == width && info.GetType() == type) { @@ -48,12 +66,39 @@ namespace ams::kern { } - uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) { - return GetAddressSpaceInfo(width, type).GetAddress(); + uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type, size_t code_size) { + MESOSPHERE_UNUSED(code_size); + return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress(); } - size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) { - return GetAddressSpaceInfo(width, type).GetSize(); + size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { + /* Extract the address space from the create process flags. */ + const auto as_flags = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask); + + /* Get the address space width. */ + const auto as_width = GetAddressSpaceWidth(flags); + + /* Get the size. */ + size_t as_size = GetAddressSpaceInfo(as_width, type).GetSize(); + + /* If we're getting size for 32-bit without alias, adjust the sizes accordingly. */ + if (as_flags == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { + switch (type) { + /* The heap space receives space that would otherwise go to the alias space. */ + case KAddressSpaceInfo::Type_Heap: + as_size += GetAddressSpaceInfo(as_width, KAddressSpaceInfo::Type_Alias).GetSize(); + break; + /* The alias space doesn't exist. */ + case KAddressSpaceInfo::Type_Alias: + as_size = 0; + break; + /* Nothing to do by default. */ + default: + break; + } + } + + return as_size; } void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) { diff --git a/libraries/libmesosphere/source/kern_k_capabilities.cpp b/libraries/libmesosphere/source/kern_k_capabilities.cpp index feb245eda..ba0359262 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -262,7 +262,14 @@ namespace ams::kern { /* Validate. */ R_UNLESS(cap.Get() == 0, svc::ResultReservedUsed()); + u32 total = 0; + if (cap.Get()) { ++total; } + if (cap.Get()) { ++total; } + if (cap.Get()) { ++total; } + R_UNLESS(total <= 1, svc::ResultInvalidCombination()); + m_debug_capabilities.Set(cap.Get()); + m_debug_capabilities.Set(cap.Get()); m_debug_capabilities.Set(cap.Get()); R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index 418d804f3..635673cd2 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -27,7 +27,8 @@ namespace ams::kern { void KDebugBase::Initialize() { /* Clear the continue flags. */ - m_continue_flags = 0; + m_continue_flags = 0; + m_is_force_debug_prod = GetCurrentProcess().CanForceDebugProd(); } bool KDebugBase::Is64Bit() const { @@ -120,8 +121,11 @@ namespace ams::kern { /* Read the memory. */ if (info.GetSvcState() != ams::svc::MemoryState_Io) { /* The memory is normal memory. */ - R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size)); + R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size, this->IsForceDebugProd())); } else { + /* Only allow IO memory to be read if not force debug prod. */ + R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidCurrentMemory()); + /* The memory is IO memory. */ R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size, info.GetState())); } @@ -269,6 +273,9 @@ namespace ams::kern { switch (state) { case KProcess::State_Created: case KProcess::State_Running: + /* Created and running processes can only be debugged if the debugger is not ForceDebugProd. */ + R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidState()); + break; case KProcess::State_Crashed: break; case KProcess::State_CreatedAttached: @@ -408,69 +415,6 @@ namespace ams::kern { /* Get the process pointer. */ KProcess * const target = this->GetProcessUnsafe(); - /* Detach from the process. */ - { - /* Lock both ourselves and the target process. */ - KScopedLightLock state_lk(target->GetStateLock()); - KScopedLightLock list_lk(target->GetListLock()); - KScopedLightLock this_lk(m_lock); - - /* Check that we're still attached. */ - if (this->IsAttached()) { - /* Lock the scheduler. */ - KScopedSchedulerLock sl; - - /* Get the process's state. */ - const KProcess::State state = target->GetState(); - - /* Check that the process is in a state where we can terminate it. */ - R_UNLESS(state != KProcess::State_Created, svc::ResultInvalidState()); - R_UNLESS(state != KProcess::State_CreatedAttached, svc::ResultInvalidState()); - - /* Decide on a new state for the process. */ - KProcess::State new_state; - if (state == KProcess::State_RunningAttached) { - /* If the process is running, transition it accordingly. */ - new_state = KProcess::State_Running; - } else if (state == KProcess::State_DebugBreak) { - /* If the process is debug breaked, transition it accordingly. */ - new_state = KProcess::State_Crashed; - - /* Suspend all the threads in the process. */ - { - auto end = target->GetThreadList().end(); - for (auto it = target->GetThreadList().begin(); it != end; ++it) { - /* Request that we suspend the thread. */ - it->RequestSuspend(KThread::SuspendType_Debug); - } - } - } else { - /* Otherwise, don't transition. */ - new_state = state; - } - - #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) - /* Clear single step on all threads. */ - { - auto end = target->GetThreadList().end(); - for (auto it = target->GetThreadList().begin(); it != end; ++it) { - it->ClearHardwareSingleStep(); - } - } - #endif - - /* Detach from the process. */ - target->ClearDebugObject(new_state); - m_is_attached = false; - - /* Close the initial reference opened to our process. */ - this->CloseProcess(); - - /* Clear our continue flags. */ - m_continue_flags = 0; - } - } - /* Terminate the process. */ target->Terminate(); @@ -962,7 +906,12 @@ namespace ams::kern { case ams::svc::DebugException_UndefinedInstruction: { MESOSPHERE_ASSERT(info->info.exception.exception_data_count == 1); - out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0]; + /* Only save the instruction if the caller is not force debug prod. */ + if (this->IsForceDebugProd()) { + out->info.exception.specific.undefined_instruction.insn = 0; + } else { + out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0]; + } } break; case ams::svc::DebugException_BreakPoint: diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index c5ef13ac5..5d9164efb 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -193,40 +193,25 @@ namespace ams::kern { R_UNLESS(this->Is64Bit(), svc::ResultInvalidCombination()); } - using ASType = KAddressSpaceInfo::Type; - const uintptr_t start_address = rx_address; const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size; - const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32; - const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; - const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type); - const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type); - const uintptr_t map_end = map_start + map_size; MESOSPHERE_ABORT_UNLESS(start_address == 0); /* Default fields in parameter to zero. */ *out = {}; /* Set fields in parameter. */ - out->code_address = map_start + start_address; + out->code_address = 0; out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize; out->program_id = m_kip_header.GetProgramId(); out->version = m_kip_header.GetVersion(); out->flags = 0; out->reslimit = ams::svc::InvalidHandle; out->system_resource_num_pages = 0; - MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); /* Copy name field. */ m_kip_header.GetName(out->name, sizeof(out->name)); - /* Apply ASLR, if needed. */ - if (enable_aslr) { - const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment); - out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment; - out->flags |= ams::svc::CreateProcessFlag_EnableAslr; - } - /* Apply other flags. */ if (this->Is64Bit()) { out->flags |= ams::svc::CreateProcessFlag_Is64Bit; @@ -236,10 +221,31 @@ namespace ams::kern { } else { out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit; } + if (enable_aslr) { + out->flags |= ams::svc::CreateProcessFlag_EnableAslr; + } /* All initial processes should disable device address space merge. */ out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; + /* Set and check code address. */ + /* NOTE: Even though Nintendo passes a size to GetAddressSpaceStart at other call sites, they pass */ + /* a number of pages here. Even though this is presumably only used for debug assertions, this is */ + /* almost certainly a bug. */ + using ASType = KAddressSpaceInfo::Type; + const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; + const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type, out->code_num_pages); + const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(out->flags), as_type); + const uintptr_t map_end = map_start + map_size; + out->code_address = map_start + start_address; + MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); + + /* Apply ASLR, if needed. */ + if (enable_aslr) { + const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment); + out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment; + } + R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 4ba4a566a..639c047d3 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -54,11 +54,11 @@ namespace ams::kern { return "Unknown "; } - constexpr const char *GetMemoryPermissionString(const KMemoryInfo &info) { - if (info.m_state == KMemoryState_Free) { + constexpr const char *GetMemoryPermissionString(const KMemoryBlock &block) { + if (block.GetState() == KMemoryState_Free) { return " "; } else { - switch (info.m_permission) { + switch (block.GetPermission()) { case KMemoryPermission_UserReadExecute: return "r-x"; case KMemoryPermission_UserRead: @@ -71,19 +71,19 @@ namespace ams::kern { } } - void DumpMemoryInfo(const KMemoryInfo &info) { - const char *state = GetMemoryStateName(info.m_state); - const char *perm = GetMemoryPermissionString(info); - const uintptr_t start = info.GetAddress(); - const uintptr_t end = info.GetLastAddress(); - const size_t kb = info.GetSize() / 1_KB; + void DumpMemoryBlock(const KMemoryBlock &block) { + const char *state = GetMemoryStateName(block.GetState()); + const char *perm = GetMemoryPermissionString(block); + const uintptr_t start = GetInteger(block.GetAddress()); + const uintptr_t end = GetInteger(block.GetLastAddress()); + const size_t kb = block.GetSize() / 1_KB; - const char l = (info.m_attribute & KMemoryAttribute_Locked) ? 'L' : '-'; - const char i = (info.m_attribute & KMemoryAttribute_IpcLocked) ? 'I' : '-'; - const char d = (info.m_attribute & KMemoryAttribute_DeviceShared) ? 'D' : '-'; - const char u = (info.m_attribute & KMemoryAttribute_Uncached) ? 'U' : '-'; + const char l = (block.GetAttribute() & KMemoryAttribute_Locked) ? 'L' : '-'; + const char i = (block.GetAttribute() & KMemoryAttribute_IpcLocked) ? 'I' : '-'; + const char d = (block.GetAttribute() & KMemoryAttribute_DeviceShared) ? 'D' : '-'; + const char u = (block.GetAttribute() & KMemoryAttribute_Uncached) ? 'U' : '-'; - MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, info.m_ipc_lock_count, info.m_device_use_count); + MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, block.GetIpcLockCount(), block.GetDeviceUseCount()); } } @@ -118,30 +118,78 @@ namespace ams::kern { MESOSPHERE_ASSERT(m_memory_block_tree.empty()); } + bool KMemoryBlockManager::GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) { + /* Check that there's room for the pages in the specified region. */ + if (num_pages + 2 * guard_pages > region_num_pages) { + return false; + } + + /* Determine the aligned start of the guarded region. */ + const KProcessAddress guarded_start = region_start + guard_pages * PageSize; + const KProcessAddress aligned_guarded_start = util::AlignDown(GetInteger(guarded_start), alignment); + KProcessAddress aligned_guarded_start_with_offset = aligned_guarded_start + offset; + if (guarded_start > aligned_guarded_start_with_offset) { + if (!util::CanAddWithoutOverflow(GetInteger(aligned_guarded_start), alignment)) { + return false; + } + aligned_guarded_start_with_offset += alignment; + } + + /* Determine the aligned end of the guarded region. */ + const KProcessAddress guarded_end = region_start + ((region_num_pages - (num_pages + guard_pages)) * PageSize); + const KProcessAddress aligned_guarded_end = util::AlignDown(GetInteger(guarded_end), alignment); + KProcessAddress aligned_guarded_end_with_offset = aligned_guarded_end + offset; + if (aligned_guarded_end_with_offset > guarded_end) { + if (aligned_guarded_end < alignment) { + return false; + } + aligned_guarded_end_with_offset -= alignment; + } + + /* Check that the extents are valid. */ + if (aligned_guarded_end_with_offset < aligned_guarded_start_with_offset) { + return false; + } + + /* Set the output extents. */ + *out_start = aligned_guarded_start_with_offset; + *out_end = aligned_guarded_end_with_offset; + return true; + } + KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const { - if (num_pages > 0) { - const KProcessAddress region_end = region_start + region_num_pages * PageSize; - const KProcessAddress region_last = region_end - 1; - for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) { - const KMemoryInfo info = it->GetMemoryInfo(); - if (region_last < info.GetAddress()) { + /* Determine the range to search in. */ + KProcessAddress search_start = Null; + KProcessAddress search_end = Null; + if (this->GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) { + /* Iterate over blocks in the search space, looking for a suitable one. */ + for (const_iterator it = this->FindIterator(search_start); it != m_memory_block_tree.cend(); it++) { + /* If our block is past the end of our search space, we're done. */ + if (search_end < it->GetAddress()) { break; } - if (info.m_state != KMemoryState_Free) { + + /* We only want to consider free blocks. */ + if (it->GetState() != KMemoryState_Free) { continue; } - KProcessAddress area = (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress(); - area += guard_pages * PageSize; + /* Determine the candidate range. */ + KProcessAddress candidate_start = Null; + KProcessAddress candidate_end = Null; + if (!this->GetRegionForFindFreeArea(std::addressof(candidate_start), std::addressof(candidate_end), it->GetAddress(), it->GetNumPages(), num_pages, alignment, offset, guard_pages)) { + continue; + } - const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset; - area = (area <= offset_area) ? offset_area : offset_area + alignment; + /* Try the suggested candidate (coercing into the search region if needed). */ + KProcessAddress candidate = candidate_start; + if (candidate < search_start) { + candidate = search_start; + } - const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize; - const KProcessAddress area_last = area_end - 1; - - if (info.GetAddress() <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= info.GetLastAddress()) { - return area; + /* Check if the candidate is valid. */ + if (candidate <= search_end && candidate <= candidate_end) { + return candidate; } } } @@ -171,7 +219,7 @@ namespace ams::kern { it = prev; } - if (address + num_pages * PageSize < it->GetMemoryInfo().GetEndAddress()) { + if (address + num_pages * PageSize < it->GetEndAddress()) { break; } } @@ -189,43 +237,39 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if (it->HasProperties(state, perm, attr)) { /* If we already have the right properties, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } else { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } it++; } @@ -245,42 +289,38 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if (it->HasProperties(test_state, test_perm, test_attr) && !it->HasProperties(state, perm, attr)) { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } else { /* If we already have the right properties, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } it++; @@ -302,34 +342,30 @@ namespace ams::kern { 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.m_address != GetInteger(cur_address)) { + if (it->GetAddress() != cur_address) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } - if (cur_info.GetSize() > remaining_size) { + if (it->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 = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Call the locked update function. */ - (std::addressof(*it)->*lock_func)(perm, cur_info.GetAddress() == address, cur_info.GetEndAddress() == end_address); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + (std::addressof(*it)->*lock_func)(perm, it->GetAddress() == address, it->GetEndAddress() == end_address); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); it++; } @@ -347,43 +383,39 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if ((it->GetAttribute() & mask) != attr) { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->UpdateAttribute(mask, attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } else { /* If we already have the right attributes, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } it++; @@ -401,8 +433,6 @@ namespace ams::kern { auto it = m_memory_block_tree.cbegin(); auto prev = it++; while (it != m_memory_block_tree.cend()) { - const KMemoryInfo prev_info = prev->GetMemoryInfo(); - const KMemoryInfo cur_info = it->GetMemoryInfo(); /* Sequential blocks which can be merged should be merged. */ if (prev->CanMergeWith(*it)) { @@ -410,17 +440,17 @@ namespace ams::kern { } /* Sequential blocks should be sequential. */ - if (prev_info.GetEndAddress() != cur_info.GetAddress()) { + if (prev->GetEndAddress() != it->GetAddress()) { return false; } /* If the block is ipc locked, it must have a count. */ - if ((cur_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && cur_info.m_ipc_lock_count == 0) { + if ((it->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && it->GetIpcLockCount() == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((cur_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && cur_info.m_device_use_count == 0) { + if ((it->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && it->GetDeviceUseCount() == 0) { return false; } @@ -430,14 +460,13 @@ namespace ams::kern { /* Our loop will miss checking the last block, potentially, so check it. */ if (prev != m_memory_block_tree.cend()) { - const KMemoryInfo prev_info = prev->GetMemoryInfo(); /* If the block is ipc locked, it must have a count. */ - if ((prev_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && prev_info.m_ipc_lock_count == 0) { + if ((prev->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && prev->GetIpcLockCount() == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((prev_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && prev_info.m_device_use_count == 0) { + if ((prev->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && prev->GetDeviceUseCount() == 0) { return false; } } @@ -450,7 +479,7 @@ namespace ams::kern { void KMemoryBlockManager::DumpBlocks() const { /* Dump each block. */ for (const auto &block : m_memory_block_tree) { - DumpMemoryInfo(block.GetMemoryInfo()); + DumpMemoryBlock(block); } } } diff --git a/libraries/libmesosphere/source/kern_k_memory_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_manager.cpp index fa533387c..aa5f5bdcc 100644 --- a/libraries/libmesosphere/source/kern_k_memory_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_manager.cpp @@ -35,7 +35,7 @@ namespace ams::kern { } - void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) { + void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts) { /* Clear the management region to zero. */ const KVirtualAddress management_region_end = management_region + management_region_size; std::memset(GetVoidPointer(management_region), 0, management_region_size); @@ -154,6 +154,17 @@ namespace ams::kern { for (size_t i = 0; i < m_num_managers; ++i) { m_managers[i].SetInitialUsedHeapSize(reserved_sizes[i]); } + + /* Determine the min heap size for all pools. */ + for (size_t i = 0; i < Pool_Count; ++i) { + /* Determine the min alignment for the pool in pages. */ + const size_t min_align_pages = 1 << min_align_shifts[i]; + + /* Determine a heap index. */ + if (const auto heap_index = KPageHeap::GetAlignedBlockIndex(min_align_pages, min_align_pages); heap_index >= 0) { + m_min_heap_indexes[i] = heap_index; + } + } } Result KMemoryManager::InitializeOptimizedMemory(u64 process_id, Pool pool) { @@ -192,8 +203,19 @@ namespace ams::kern { return Null; } - /* Lock the pool that we're allocating from. */ + /* Determine the pool and direction we're allocating from. */ const auto [pool, dir] = DecodeOption(option); + + /* Check that we're allocating a correctly aligned number of pages. */ + const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]); + if (!util::IsAligned(num_pages, min_align_pages)) { + return Null; + } + + /* Update our alignment. */ + align_pages = std::max(align_pages, min_align_pages); + + /* Lock the pool that we're allocating from. */ KScopedLightLock lk(m_pool_locks[pool]); /* Choose a heap based on our page size request. */ @@ -226,6 +248,13 @@ namespace ams::kern { } Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index) { + /* Check that we're allocating a correctly aligned number of pages. */ + const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]); + R_UNLESS(util::IsAligned(num_pages, min_align_pages), svc::ResultInvalidSize()); + + /* Adjust our min heap index to the pool minimum if needed. */ + min_heap_index = std::max(min_heap_index, m_min_heap_indexes[pool]); + /* Choose a heap based on our page size request. */ const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory()); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 2e90d924e..ad42a62a4 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -141,10 +141,10 @@ namespace ams::kern { /* Define helpers. */ auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); + return KAddressSpaceInfo::GetAddressSpaceStart(flags, type, code_size); }; auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); + return KAddressSpaceInfo::GetAddressSpaceSize(flags, type); }; /* Default to zero alias region extra size. */ @@ -155,12 +155,6 @@ namespace ams::kern { size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); - /* Adjust heap/alias size if we don't have an alias region. */ - if ((flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { - heap_region_size += alias_region_size; - alias_region_size = 0; - } - /* Set code regions and determine remaining sizes. */ KProcessAddress process_code_start; KProcessAddress process_code_end; @@ -664,11 +658,11 @@ namespace ams::kern { } } - Result KPageTableBase::CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { + Result KPageTableBase::CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { /* Validate the states match expectation. */ - R_UNLESS((info.m_state & state_mask) == state, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_permission & perm_mask) == perm, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_attribute & attr_mask) == attr, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetState() & state_mask) == state, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetPermission() & perm_mask) == perm, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetAttribute() & attr_mask) == attr, svc::ResultInvalidCurrentMemory()); R_SUCCEED(); } @@ -679,28 +673,26 @@ namespace ams::kern { /* Get information about the first block. */ const KProcessAddress last_addr = addr + size - 1; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); - KMemoryInfo info = it->GetMemoryInfo(); /* If the start address isn't aligned, we need a block. */ - const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; + const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) ? 1 : 0; while (true) { /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= info.GetLastAddress()) { + if (last_addr <= it->GetLastAddress()) { break; } /* Advance our iterator. */ it++; MESOSPHERE_ASSERT(it != m_memory_block_manager.cend()); - info = it->GetMemoryInfo(); } /* If the end address isn't aligned, we need a block. */ - const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; + const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != it->GetEndAddress()) ? 1 : 0; if (out_blocks_needed != nullptr) { *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; @@ -712,31 +704,27 @@ namespace ams::kern { Result KPageTableBase::CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr) const { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - /* Get information about the first block. */ - KMemoryInfo info = it->GetMemoryInfo(); - /* Validate all blocks in the range have correct state. */ - const KMemoryState first_state = info.m_state; - const KMemoryPermission first_perm = info.m_permission; - const KMemoryAttribute first_attr = info.m_attribute; + const KMemoryState first_state = it->GetState(); + const KMemoryPermission first_perm = it->GetPermission(); + const KMemoryAttribute first_attr = it->GetAttribute(); while (true) { /* Validate the current block. */ - R_UNLESS(info.m_state == first_state, svc::ResultInvalidCurrentMemory()); - R_UNLESS(info.m_permission == first_perm, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_attribute | ignore_attr) == (first_attr | ignore_attr), svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetState() == first_state, svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetPermission() == first_perm, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetAttribute() | ignore_attr) == (first_attr | ignore_attr), svc::ResultInvalidCurrentMemory()); /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= info.GetLastAddress()) { + if (last_addr <= it->GetLastAddress()) { break; } /* Advance our iterator. */ it++; MESOSPHERE_ASSERT(it != m_memory_block_manager.cend()); - info = it->GetMemoryInfo(); } /* Write output state. */ @@ -752,7 +740,7 @@ namespace ams::kern { /* If the end address isn't aligned, we need a block. */ if (out_blocks_needed != nullptr) { - const size_t blocks_for_end_align = (util::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress()) ? 1 : 0; + const size_t blocks_for_end_align = (util::AlignDown(GetInteger(last_addr), PageSize) + PageSize != it->GetEndAddress()) ? 1 : 0; *out_blocks_needed = blocks_for_end_align; } @@ -1176,17 +1164,14 @@ namespace ams::kern { { KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(dst_address); while (true) { - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Check if the memory has code flag. */ - if ((info.GetState() & KMemoryState_FlagCode) != 0) { + if ((it->GetState() & KMemoryState_FlagCode) != 0) { any_code_pages = true; break; } /* Check if we're done. */ - if (dst_address + size - 1 <= info.GetLastAddress()) { + if (dst_address + size - 1 <= it->GetLastAddress()) { break; } @@ -1348,35 +1333,37 @@ namespace ams::kern { KProcessAddress KPageTableBase::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const { KProcessAddress address = Null; - if (num_pages <= region_num_pages) { + KProcessAddress search_start = Null; + KProcessAddress search_end = Null; + if (m_memory_block_manager.GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) { if (this->IsAslrEnabled()) { /* Try to directly find a free area up to 8 times. */ for (size_t i = 0; i < 8; i++) { - const size_t random_offset = KSystemControl::GenerateRandomRange(0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) * alignment; - const KProcessAddress candidate = util::AlignDown(GetInteger(region_start + random_offset), alignment) + offset; + const size_t random_offset = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment) * alignment; + const KProcessAddress candidate = search_start + random_offset; - KMemoryInfo info; - ams::svc::PageInfo page_info; - MESOSPHERE_R_ABORT_UNLESS(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), candidate)); + KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate); + MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end()); - if (info.m_state != KMemoryState_Free) { continue; } - if (!(region_start <= candidate)) { continue; } - if (!(info.GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= info.GetLastAddress())) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= region_start + region_num_pages * PageSize - 1)) { continue; } + if (it->GetState() != KMemoryState_Free) { continue; } + if (!(it->GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; } + if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= it->GetLastAddress())) { continue; } address = candidate; break; } + /* Fall back to finding the first free area with a random offset. */ if (address == Null) { /* NOTE: Nintendo does not account for guard pages here. */ /* This may theoretically cause an offset to be chosen that cannot be mapped. */ /* We will account for guard pages. */ - const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages); - address = m_memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages); + const size_t offset_blocks = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment); + const auto region_end = region_start + region_num_pages * PageSize; + address = m_memory_block_manager.FindFreeArea(search_start + offset_blocks * alignment, (region_end - (search_start + offset_blocks * alignment)) / PageSize, num_pages, alignment, offset, guard_pages); } } + /* Find the first free area. */ if (address == Null) { address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages, alignment, offset, guard_pages); @@ -1393,10 +1380,8 @@ namespace ams::kern { /* Iterate, counting blocks with the desired state. */ size_t total_size = 0; for (KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(m_address_space_start); it != m_memory_block_manager.end(); ++it) { - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - if (info.GetState() == state) { - total_size += info.GetSize(); + if (it->GetState() == state) { + total_size += it->GetSize(); } } @@ -1488,17 +1473,14 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Determine the range to map. */ - KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address)); - const KProcessAddress map_end_address = std::min(info.GetEndAddress(), GetInteger(end_address)); + KProcessAddress map_address = std::max(GetInteger(it->GetAddress()), GetInteger(start_address)); + const KProcessAddress map_end_address = std::min(GetInteger(it->GetEndAddress()), GetInteger(end_address)); MESOSPHERE_ABORT_UNLESS(map_end_address != map_address); /* Determine if we should disable head merge. */ - const bool disable_head_merge = info.GetAddress() >= GetInteger(start_address) && (info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Normal) != 0; - const KPageProperties map_properties = { info.GetPermission(), false, false, disable_head_merge ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; + const bool disable_head_merge = it->GetAddress() >= GetInteger(start_address) && (it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Normal) != 0; + const KPageProperties map_properties = { it->GetPermission(), false, false, disable_head_merge ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; /* While we have pages to map, map them. */ size_t map_pages = (map_end_address - map_address) / PageSize; @@ -1527,7 +1509,7 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } @@ -1802,13 +1784,10 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); - /* Perform mapping operation. */ - const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; - const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions; - R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, operation, false)); - - /* Update the blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + /* If we're creating an executable mapping, take and immediately release the scheduler lock. This will force a reschedule. */ + if (is_x) { + KScopedSchedulerLock sl; + } /* Ensure cache coherency, if we're setting pages as executable. */ if (is_x) { @@ -1818,6 +1797,19 @@ namespace ams::kern { cpu::InvalidateEntireInstructionCache(); } + /* Perform mapping operation. */ + const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; + const auto operation = was_x ? OperationType_ChangePermissionsAndRefresh : OperationType_ChangePermissions; + R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, operation, false)); + + /* Update the blocks. */ + m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + + /* Ensure cache coherency, if we're setting pages as executable. */ + if (was_x) { + cpu::InvalidateEntireInstructionCache(); + } + R_SUCCEED(); } @@ -2032,19 +2024,18 @@ namespace ams::kern { address = util::AlignDown(GetInteger(address), PageSize); /* Verify that we can query the address. */ - KMemoryInfo info; - ams::svc::PageInfo page_info; - R_TRY(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), address)); + KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); + R_UNLESS(it != m_memory_block_manager.end(), svc::ResultInvalidCurrentMemory()); /* Check the memory state. */ - R_TRY(this->CheckMemoryState(info, KMemoryState_FlagCanQueryPhysical, KMemoryState_FlagCanQueryPhysical, KMemoryPermission_UserReadExecute, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(it, KMemoryState_FlagCanQueryPhysical, KMemoryState_FlagCanQueryPhysical, KMemoryPermission_UserReadExecute, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); /* Prepare to traverse. */ KPhysicalAddress phys_addr; size_t phys_size; - KProcessAddress virt_addr = info.GetAddress(); - KProcessAddress end_addr = info.GetEndAddress(); + KProcessAddress virt_addr = it->GetAddress(); + KProcessAddress end_addr = it->GetEndAddress(); /* Perform traversal. */ { @@ -2557,6 +2548,11 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); + /* Ensure cache coherency, if we're mapping executable pages. */ + if ((perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) { + cpu::InvalidateEntireInstructionCache(); + } + /* Perform mapping operation. */ const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); @@ -2580,8 +2576,9 @@ namespace ams::kern { KScopedLightLock lk(m_general_lock); /* Check if state allows us to unmap. */ + KMemoryPermission old_perm; size_t num_allocator_blocks; - R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(nullptr, std::addressof(old_perm), nullptr, std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); /* Check that the page group is valid. */ R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), svc::ResultInvalidCurrentMemory()); @@ -2598,6 +2595,11 @@ namespace ams::kern { const KPageProperties properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), address, num_pages, Null, false, properties, OperationType_Unmap, false)); + /* Ensure cache coherency, if we're mapping executable pages. */ + if ((old_perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) { + cpu::InvalidateEntireInstructionCache(); + } + /* Update the blocks. */ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal); @@ -2711,18 +2713,37 @@ namespace ams::kern { R_RETURN(cpu::InvalidateDataCache(GetVoidPointer(address), size)); } - Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { + bool KPageTableBase::CanReadWriteDebugMemory(KProcessAddress address, size_t size, bool force_debug_prod) { + /* Check pre-conditions. */ + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + /* If the memory is debuggable and user-readable, we can perform the access. */ + if (R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_NotMapped | KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { + return true; + } + + /* If we're in debug mode, and the process isn't force debug prod, check if the memory is debuggable and kernel-readable and user-executable. */ + if (KTargetSystem::IsDebugMode() && !force_debug_prod) { + if (R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_KernelRead | KMemoryPermission_UserExecute, KMemoryPermission_KernelRead | KMemoryPermission_UserExecute, KMemoryAttribute_None, KMemoryAttribute_None))) { + return true; + } + } + + /* If neither of the above checks passed, we can't access the memory. */ + return false; + } + + Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod) { /* Lightly validate the region is in range. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); /* Lock the table. */ KScopedLightLock lk(m_general_lock); - /* Require that the memory either be user readable or debuggable. */ - const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + /* Require that the memory either be user-readable-and-mapped or debug-accessible. */ + const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_NotMapped | KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); if (!can_read) { - const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); - R_UNLESS(can_debug, svc::ResultInvalidCurrentMemory()); + R_UNLESS(this->CanReadWriteDebugMemory(address, size, force_debug_prod), svc::ResultInvalidCurrentMemory()); } /* Get the impl. */ @@ -2804,11 +2825,10 @@ namespace ams::kern { /* Lock the table. */ KScopedLightLock lk(m_general_lock); - /* Require that the memory either be user writable or debuggable. */ - const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); - if (!can_read) { - const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); - R_UNLESS(can_debug, svc::ResultInvalidCurrentMemory()); + /* Require that the memory either be user-writable-and-mapped or debug-accessible. */ + const bool can_write = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_NotMapped | KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); + if (!can_write) { + R_UNLESS(this->CanReadWriteDebugMemory(address, size, false), svc::ResultInvalidCurrentMemory()); } /* Get the impl. */ @@ -3827,15 +3847,15 @@ namespace ams::kern { switch (dst_state) { case KMemoryState_Ipc: test_state = KMemoryState_FlagCanUseIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_IpcLocked)); break; case KMemoryState_NonSecureIpc: test_state = KMemoryState_FlagCanUseNonSecureIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); break; case KMemoryState_NonDeviceIpc: test_state = KMemoryState_FlagCanUseNonDeviceIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); break; default: R_THROW(svc::ResultInvalidCombination()); @@ -3854,27 +3874,25 @@ namespace ams::kern { /* Iterate, mapping as needed. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(aligned_src_start); while (true) { - const KMemoryInfo info = it->GetMemoryInfo(); - /* Validate the current block. */ - R_TRY(this->CheckMemoryState(info, test_state, test_state, test_perm, test_perm, test_attr_mask, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(it, test_state, test_state, test_perm, test_perm, test_attr_mask, KMemoryAttribute_None)); - if (mapping_src_start < mapping_src_end && GetInteger(mapping_src_start) < info.GetEndAddress() && info.GetAddress() < GetInteger(mapping_src_end)) { - const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start) ? info.GetAddress() : GetInteger(mapping_src_start); - const auto cur_end = mapping_src_last >= info.GetLastAddress() ? info.GetEndAddress() : GetInteger(mapping_src_end); + if (mapping_src_start < mapping_src_end && GetInteger(mapping_src_start) < GetInteger(it->GetEndAddress()) && GetInteger(it->GetAddress()) < GetInteger(mapping_src_end)) { + const auto cur_start = it->GetAddress() >= GetInteger(mapping_src_start) ? GetInteger(it->GetAddress()) : GetInteger(mapping_src_start); + const auto cur_end = mapping_src_last >= GetInteger(it->GetLastAddress()) ? GetInteger(it->GetEndAddress()) : GetInteger(mapping_src_end); const size_t cur_size = cur_end - cur_start; - if (info.GetAddress() < GetInteger(mapping_src_start)) { + if (GetInteger(it->GetAddress()) < GetInteger(mapping_src_start)) { ++blocks_needed; } - if (mapping_src_last < info.GetLastAddress()) { + if (mapping_src_last < GetInteger(it->GetLastAddress())) { ++blocks_needed; } /* Set the permissions on the block, if we need to. */ - if ((info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != src_perm) { - const DisableMergeAttribute head_body_attr = (GetInteger(mapping_src_start) >= info.GetAddress()) ? DisableMergeAttribute_DisableHeadAndBody : DisableMergeAttribute_None; - const DisableMergeAttribute tail_attr = (cur_end == GetInteger(mapping_src_end)) ? DisableMergeAttribute_DisableTail : DisableMergeAttribute_None; + if ((it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != src_perm) { + const DisableMergeAttribute head_body_attr = (GetInteger(mapping_src_start) >= GetInteger(it->GetAddress())) ? DisableMergeAttribute_DisableHeadAndBody : DisableMergeAttribute_None; + const DisableMergeAttribute tail_attr = (cur_end == GetInteger(mapping_src_end)) ? DisableMergeAttribute_DisableTail : DisableMergeAttribute_None; const KPageProperties properties = { src_perm, false, false, static_cast(head_body_attr | tail_attr) }; R_TRY(this->Operate(page_list, cur_start, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } @@ -3884,7 +3902,7 @@ namespace ams::kern { } /* If the block is at the end, we're done. */ - if (aligned_src_last <= info.GetLastAddress()) { + if (aligned_src_last <= GetInteger(it->GetLastAddress())) { break; } @@ -4248,56 +4266,50 @@ namespace ams::kern { const auto mapped_last = mapped_end - 1; /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = start_it; + KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = cur_it; ++next_it; - /* Get the current block info. */ - KMemoryInfo cur_info = start_it->GetMemoryInfo(); - /* Create tracking variables. */ - KProcessAddress cur_address = cur_info.GetAddress(); - size_t cur_size = cur_info.GetSize(); - bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); - bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; - bool first = cur_info.GetIpcDisableMergeCount() == 1 && (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; + KProcessAddress cur_address = cur_it->GetAddress(); + size_t cur_size = cur_it->GetSize(); + bool cur_perm_eq = cur_it->GetPermission() == cur_it->GetOriginalPermission(); + bool cur_needs_set_perm = !cur_perm_eq && cur_it->GetIpcLockCount() == 1; + bool first = cur_it->GetIpcDisableMergeCount() == 1 && (cur_it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; while ((GetInteger(cur_address) + cur_size - 1) < mapped_last) { /* Check that we have a next block. */ MESOSPHERE_ABORT_UNLESS(next_it != m_memory_block_manager.end()); - /* Get the next info. */ - const KMemoryInfo next_info = next_it->GetMemoryInfo(); - /* Check if we can consolidate the next block's permission set with the current one. */ - const bool next_perm_eq = next_info.GetPermission() == next_info.GetOriginalPermission(); - const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1; - if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) { + const bool next_perm_eq = next_it->GetPermission() == next_it->GetOriginalPermission(); + const bool next_needs_set_perm = !next_perm_eq && next_it->GetIpcLockCount() == 1; + if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_it->GetOriginalPermission() == next_it->GetOriginalPermission()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_info.GetSize(); + cur_size += next_it->GetSize(); } else { /* We have to operate on the current block. */ if ((cur_needs_set_perm || first) && !cur_perm_eq) { - const KPageProperties properties = { cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } /* Advance. */ - cur_address = next_info.GetAddress(); - cur_size = next_info.GetSize(); + cur_address = next_it->GetAddress(); + cur_size = next_it->GetSize(); first = false; } /* Advance. */ - cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - ++next_it; + + cur_it = next_it++; } /* Process the last block. */ if ((first || cur_needs_set_perm) && !cur_perm_eq) { - const KPageProperties properties = { cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } } @@ -4306,41 +4318,37 @@ namespace ams::kern { /* Iterate, reprotecting as needed. */ { /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = start_it; + KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = cur_it; ++next_it; /* Validate the current block. */ - KMemoryInfo cur_info = start_it->GetMemoryInfo(); - MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(cur_info, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(cur_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); /* Create tracking variables. */ - KProcessAddress cur_address = cur_info.GetAddress(); - size_t cur_size = cur_info.GetSize(); - bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); - bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; - bool first = cur_info.GetIpcDisableMergeCount() == 1 && (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; + KProcessAddress cur_address = cur_it->GetAddress(); + size_t cur_size = cur_it->GetSize(); + bool cur_perm_eq = cur_it->GetPermission() == cur_it->GetOriginalPermission(); + bool cur_needs_set_perm = !cur_perm_eq && cur_it->GetIpcLockCount() == 1; + bool first = cur_it->GetIpcDisableMergeCount() == 1 && (cur_it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; while ((cur_address + cur_size - 1) < mapping_last) { /* Check that we have a next block. */ MESOSPHERE_ABORT_UNLESS(next_it != m_memory_block_manager.end()); - /* Get the next info. */ - const KMemoryInfo next_info = next_it->GetMemoryInfo(); - /* Validate the next block. */ - MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(next_info, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(next_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); /* Check if we can consolidate the next block's permission set with the current one. */ - const bool next_perm_eq = next_info.GetPermission() == next_info.GetOriginalPermission(); - const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1; - if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) { + const bool next_perm_eq = next_it->GetPermission() == next_it->GetOriginalPermission(); + const bool next_needs_set_perm = !next_perm_eq && next_it->GetIpcLockCount() == 1; + if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_it->GetOriginalPermission() == next_it->GetOriginalPermission()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_info.GetSize(); + cur_size += next_it->GetSize(); } else { /* We have to operate on the current block. */ if ((cur_needs_set_perm || first) && !cur_perm_eq) { - const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_needs_set_perm ? cur_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } @@ -4348,24 +4356,24 @@ namespace ams::kern { mapped_size += cur_size; /* Advance. */ - cur_address = next_info.GetAddress(); - cur_size = next_info.GetSize(); + cur_address = next_it->GetAddress(); + cur_size = next_it->GetSize(); first = false; } /* Advance. */ - cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - ++next_it; + + cur_it = next_it++; } /* Process the last block. */ - const auto lock_count = cur_info.GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = cur_it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); if ((first || cur_needs_set_perm || (lock_count == 1)) && !cur_perm_eq) { const DisableMergeAttribute head_body_attr = first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None; const DisableMergeAttribute tail_attr = lock_count == 1 ? DisableMergeAttribute_EnableTail : DisableMergeAttribute_None; - const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { cur_needs_set_perm ? cur_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } } @@ -4398,38 +4406,36 @@ namespace ams::kern { /* Iterate over blocks, fixing permissions. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); while (true) { - const KMemoryInfo info = it->GetMemoryInfo(); - - const auto cur_start = info.GetAddress() >= GetInteger(src_map_start) ? info.GetAddress() : GetInteger(src_map_start); - const auto cur_end = src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress(); + const auto cur_start = it->GetAddress() >= GetInteger(src_map_start) ? it->GetAddress() : GetInteger(src_map_start); + const auto cur_end = src_map_last <= it->GetLastAddress() ? src_map_end : it->GetEndAddress(); /* If we can, fix the protections on the block. */ - if ((info.GetIpcLockCount() == 0 && (info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || - (info.GetIpcLockCount() != 0 && (info.GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) + if ((it->GetIpcLockCount() == 0 && (it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || + (it->GetIpcLockCount() != 0 && (it->GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) { /* Check if we actually need to fix the protections on the block. */ - if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) || (info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) { - const bool start_nc = (info.GetAddress() == GetInteger(src_map_start)) ? ((info.GetDisableMergeAttribute() & (KMemoryBlockDisableMergeAttribute_Locked | KMemoryBlockDisableMergeAttribute_IpcLeft)) == 0) : info.GetAddress() <= GetInteger(src_map_start); + if (cur_end == src_map_end || it->GetAddress() <= GetInteger(src_map_start) || (it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) { + const bool start_nc = (it->GetAddress() == GetInteger(src_map_start)) ? ((it->GetDisableMergeAttribute() & (KMemoryBlockDisableMergeAttribute_Locked | KMemoryBlockDisableMergeAttribute_IpcLeft)) == 0) : it->GetAddress() <= GetInteger(src_map_start); const DisableMergeAttribute head_body_attr = start_nc ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None; DisableMergeAttribute tail_attr; - if (cur_end == src_map_end && info.GetEndAddress() == src_map_end) { + if (cur_end == src_map_end && it->GetEndAddress() == src_map_end) { auto next_it = it; ++next_it; - const auto lock_count = info.GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); tail_attr = lock_count == 0 ? DisableMergeAttribute_EnableTail : DisableMergeAttribute_None; } else { tail_attr = DisableMergeAttribute_None; } - const KPageProperties properties = { info.GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(page_list, cur_start, (cur_end - cur_start) / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } } /* If we're past the end of the region, we're done. */ - if (src_map_last <= info.GetLastAddress()) { + if (src_map_last <= it->GetLastAddress()) { break; } @@ -4468,24 +4474,21 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { - if (info.GetState() != KMemoryState_Free) { + if (last_address <= it->GetLastAddress()) { + if (it->GetState() != KMemoryState_Free) { mapped_size += (last_address + 1 - cur_address); } break; } /* Track the memory if it's mapped. */ - if (info.GetState() != KMemoryState_Free) { - mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; + if (it->GetState() != KMemoryState_Free) { + mapped_size += it->GetEndAddress() - cur_address; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4527,21 +4530,18 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - - const bool is_free = info.GetState() == KMemoryState_Free; + const bool is_free = it->GetState() == KMemoryState_Free; if (is_free) { - if (info.GetAddress() < GetInteger(address)) { + if (it->GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < info.GetLastAddress()) { + if (last_address < it->GetLastAddress()) { ++num_allocator_blocks; } } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { if (!is_free) { checked_mapped_size += (last_address + 1 - cur_address); } @@ -4550,11 +4550,11 @@ namespace ams::kern { /* Track the memory if it's mapped. */ if (!is_free) { - checked_mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; + checked_mapped_size += it->GetEndAddress() - cur_address; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4594,26 +4594,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If the memory state is free, we mapped it and need to unmap it. */ - if (info.GetState() == KMemoryState_Free) { + if (it->GetState() == KMemoryState_Free) { /* Determine the range to unmap. */ const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_unmap_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(it->GetEndAddress() - cur_address, last_unmap_address + 1 - cur_address) / PageSize; /* Unmap. */ MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_pages, Null, false, unmap_properties, OperationType_Unmap, true)); } /* Check if we're done. */ - if (last_unmap_address <= info.GetLastAddress()) { + if (last_unmap_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } } @@ -4632,14 +4629,11 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If it's unmapped, we need to map it. */ - if (info.GetState() == KMemoryState_Free) { + if (it->GetState() == KMemoryState_Free) { /* Determine the range to map. */ const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, cur_address == this->GetAliasRegionStart() ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; - size_t map_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; + size_t map_pages = std::min(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; /* While we have pages to map, map them. */ { @@ -4680,12 +4674,12 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4737,26 +4731,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Verify the memory's state. */ - const bool is_normal = info.GetState() == KMemoryState_Normal && info.GetAttribute() == 0; - const bool is_free = info.GetState() == KMemoryState_Free; + const bool is_normal = it->GetState() == KMemoryState_Normal && it->GetAttribute() == 0; + const bool is_free = it->GetState() == KMemoryState_Free; R_UNLESS(is_normal || is_free, svc::ResultInvalidCurrentMemory()); if (is_normal) { - R_UNLESS(info.GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); if (map_start_address == Null) { map_start_address = cur_address; } - map_last_address = (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address; + map_last_address = (last_address >= it->GetLastAddress()) ? it->GetLastAddress() : last_address; - if (info.GetAddress() < GetInteger(address)) { + if (it->GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < info.GetLastAddress()) { + if (last_address < it->GetLastAddress()) { ++num_allocator_blocks; } @@ -4764,12 +4755,12 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4802,26 +4793,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If the memory state is normal, we need to unmap it. */ - if (info.GetState() == KMemoryState_Normal) { + if (it->GetState() == KMemoryState_Normal) { /* Determine the range to unmap. */ const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; /* Unmap. */ MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_pages, Null, false, unmap_properties, OperationType_Unmap, false)); } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 789bdbc09..08a79f5c0 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -220,18 +220,8 @@ namespace ams::kern { m_running_thread_switch_counts[i] = 0; } - /* Set max memory based on address space type. */ - switch ((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask)) { - case ams::svc::CreateProcessFlag_AddressSpace32Bit: - case ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated: - case ams::svc::CreateProcessFlag_AddressSpace64Bit: - m_max_process_memory = m_page_table.GetHeapRegionSize(); - break; - case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: - m_max_process_memory = m_page_table.GetHeapRegionSize() + m_page_table.GetAliasRegionSize(); - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } + /* Set max memory. */ + m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(m_flags), KAddressSpaceInfo::Type_Heap); /* Generate random entropy. */ KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); @@ -299,7 +289,7 @@ namespace ams::kern { /* Setup page table. */ { const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -378,7 +368,7 @@ namespace ams::kern { /* Setup page table. */ { const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -934,7 +924,6 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(m_main_thread_stack_size == 0); /* Ensure that we're allocating a valid stack. */ - stack_size = util::AlignUp(stack_size, PageSize); R_UNLESS(stack_size + m_code_size <= m_max_process_memory, svc::ResultOutOfMemory()); R_UNLESS(stack_size + m_code_size >= m_code_size, svc::ResultOutOfMemory()); diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index fe0b56996..dece074ef 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -102,10 +102,10 @@ namespace ams::kern { /* Randomness for Initialization. */ void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) { - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } for (size_t i = 0; i < count; ++i) { @@ -114,41 +114,24 @@ namespace ams::kern { } u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) { - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); } /* System Initialization. */ + void KSystemControlBase::ConfigureKTargetSystem() { + /* By default, use the default config set in the KTargetSystem header. */ + } + void KSystemControlBase::InitializePhase1() { - /* Configure KTargetSystem. */ + /* Enable KTargetSystem. */ { - /* Set IsDebugMode. */ - { - KTargetSystem::SetIsDebugMode(true); - - /* If debug mode, we want to initialize uart logging. */ - KTargetSystem::EnableDebugLogging(true); - } - - /* Set Kernel Configuration. */ - { - KTargetSystem::EnableDebugMemoryFill(false); - KTargetSystem::EnableUserExceptionHandlers(true); - KTargetSystem::EnableDynamicResourceLimits(true); - KTargetSystem::EnableUserPmuAccess(false); - } - - /* Set Kernel Debugging. */ - { - /* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */ - /* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */ - KTargetSystem::EnableKernelDebugging(true); - } + KTargetSystem::SetInitialized(); } /* Initialize random and resource limit. */ @@ -157,9 +140,9 @@ namespace ams::kern { void KSystemControlBase::InitializePhase1Base(u64 seed) { /* Initialize the rng, if we somehow haven't already. */ - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } /* Initialize debug logging. */ diff --git a/libraries/libmesosphere/source/kern_k_system_resource.cpp b/libraries/libmesosphere/source/kern_k_system_resource.cpp index 876d6129d..fc4876252 100644 --- a/libraries/libmesosphere/source/kern_k_system_resource.cpp +++ b/libraries/libmesosphere/source/kern_k_system_resource.cpp @@ -59,7 +59,9 @@ namespace ams::kern { memory_reservation.Commit(); /* Open reference to our resource limit. */ - m_resource_limit->Open(); + if (m_resource_limit != nullptr) { + m_resource_limit->Open(); + } /* Set ourselves as initialized. */ m_is_initialized = true; @@ -76,11 +78,14 @@ namespace ams::kern { /* Free our secure memory. */ KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool); - /* Release the memory reservation. */ - m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); + /* Clean up our resource usage. */ + if (m_resource_limit != nullptr) { + /* Release the memory reservation. */ + m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); - /* Close reference to our resource limit. */ - m_resource_limit->Close(); + /* Close reference to our resource limit. */ + m_resource_limit->Close(); + } } size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool) { diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 4ec7aa1dd..74b39acd3 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -1438,7 +1438,10 @@ namespace ams::kern { this->SetState(ThreadState_Waiting); /* Set our wait queue. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdangling-pointer" m_wait_queue = queue; + #pragma GCC diagnostic pop } void KThread::NotifyAvailable(KSynchronizationObject *signaled_object, Result wait_result) { diff --git a/libraries/libmesosphere/source/kern_kernel.cpp b/libraries/libmesosphere/source/kern_kernel.cpp index cc80d9fbe..9660d906d 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -74,43 +74,45 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(rc_size < size); size -= rc_size; + /* Determine dynamic page managers. */ + KDynamicPageManager * const app_dynamic_page_manager = nullptr; + KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr; + /* Initialize the resource managers' shared page manager. */ g_resource_manager_page_manager.Initialize(address, size, std::max(PageSize, KPageBufferSlabHeap::BufferSize)); /* Initialize the KPageBuffer slab heap. */ KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager); - /* Initialize the fixed-size slabheaps. */ - s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize); - s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize); + /* Initialize the block info heap. */ s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize); + /* Initialize the system slab managers. */ + s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap)); + s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize); + s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap)); + + /* Initialize the application slab managers. */ + s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap)); + s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize); + s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap)); + /* Reserve all but a fixed number of remaining pages for the page table heap. */ const size_t num_pt_pages = g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() - ReservedDynamicPageCount; s_page_table_heap.Initialize(std::addressof(g_resource_manager_page_manager), num_pt_pages, GetPointer(address + size)); - /* Setup the slab managers. */ - KDynamicPageManager * const app_dynamic_page_manager = nullptr; - KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr; - s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap)); - s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap)); - - s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap)); - s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap)); - - s_app_page_table_manager.Initialize(app_dynamic_page_manager, std::addressof(s_page_table_heap)); + /* Create and initialize the system system resource. */ s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap)); + KAutoObject::Create(std::addressof(s_sys_system_resource)); + s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager); + + /* Create and initialize the application system resource. */ + s_app_page_table_manager.Initialize(app_dynamic_page_manager, std::addressof(s_page_table_heap)); + KAutoObject::Create(std::addressof(s_app_system_resource)); + s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager); /* Check that we have the correct number of dynamic pages available. */ MESOSPHERE_ABORT_UNLESS(g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() == ReservedDynamicPageCount); - - /* Create the system page table managers. */ - KAutoObject::Create(std::addressof(s_app_system_resource)); - KAutoObject::Create(std::addressof(s_sys_system_resource)); - - /* Set the managers for the system resources. */ - s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager); - s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager); } void Kernel::PrintLayout() { diff --git a/libraries/libmesosphere/source/kern_main.cpp b/libraries/libmesosphere/source/kern_main.cpp index 0f1782c2a..160bb495d 100644 --- a/libraries/libmesosphere/source/kern_main.cpp +++ b/libraries/libmesosphere/source/kern_main.cpp @@ -56,8 +56,9 @@ namespace ams::kern { { const auto &management_region = KMemoryLayout::GetPoolManagementRegion(); MESOSPHERE_ABORT_UNLESS(management_region.GetEndAddress() != 0); + static_assert(util::size(MinimumMemoryManagerAlignmentShifts) == KMemoryManager::Pool_Count); - Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize()); + Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize(), MinimumMemoryManagerAlignmentShifts); } /* Copy the Initial Process Binary to safe memory. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp index 68eb61e84..2b495ad45 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp @@ -41,17 +41,22 @@ namespace ams::kern::svc { case ams::svc::ArbitrationType_WaitIfLessThan: case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: case ams::svc::ArbitrationType_WaitIfEqual: + case ams::svc::ArbitrationType_WaitIfEqual64: return true; default: return false; } } - Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { /* Validate input. */ - R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); - R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); - R_UNLESS(IsValidArbitrationType(arb_type), svc::ResultInvalidEnumValue()); + R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); + if (arb_type == ams::svc::ArbitrationType_WaitIfEqual64) { + R_UNLESS(util::IsAligned(address, sizeof(int64_t)), svc::ResultInvalidAddress()); + } else { + R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); + } + R_UNLESS(IsValidArbitrationType(arb_type), svc::ResultInvalidEnumValue()); /* Convert timeout from nanoseconds to ticks. */ s64 timeout; @@ -85,7 +90,7 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ - Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } @@ -95,7 +100,7 @@ namespace ams::kern::svc { /* ============================= 64From32 ABI ============================= */ - Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp index 369885355..986654ce4 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp @@ -24,6 +24,9 @@ namespace ams::kern::svc { constexpr inline int32_t MaximumDebuggableThreadCount = 0x60; Result DebugActiveProcess(ams::svc::Handle *out_handle, uint64_t process_id) { + /* Check that the SVC can be used. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the process from its id. */ KProcess *process = KProcess::GetProcessFromId(process_id); R_UNLESS(process != nullptr, svc::ResultInvalidProcessId()); @@ -32,9 +35,8 @@ namespace ams::kern::svc { ON_SCOPE_EXIT { process->Close(); }; /* Check that the debugging is allowed. */ - if (!process->IsPermittedDebug()) { - R_UNLESS(GetCurrentProcess().CanForceDebug(), svc::ResultInvalidState()); - } + const bool allowable = process->IsPermittedDebug() || GetCurrentProcess().CanForceDebug() || GetCurrentProcess().CanForceDebugProd(); + R_UNLESS(allowable, svc::ResultInvalidState()); /* Disallow debugging one's own processs, to prevent softlocks. */ R_UNLESS(process != GetCurrentProcessPointer(), svc::ResultInvalidState()); @@ -92,6 +94,9 @@ namespace ams::kern::svc { template Result GetDebugEvent(KUserPointer out_info, ams::svc::Handle debug_handle) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); @@ -164,6 +169,9 @@ namespace ams::kern::svc { } Result GetDebugThreadContext(KUserPointer out_context, ams::svc::Handle debug_handle, uint64_t thread_id, uint32_t context_flags) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Validate the context flags. */ R_UNLESS((context_flags | ams::svc::ThreadContextFlag_All) == ams::svc::ThreadContextFlag_All, svc::ResultInvalidEnumValue()); @@ -220,6 +228,9 @@ namespace ams::kern::svc { } Result QueryDebugProcessMemory(ams::svc::MemoryInfo *out_memory_info, ams::svc::PageInfo *out_page_info, ams::svc::Handle debug_handle, uintptr_t address) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); @@ -261,6 +272,9 @@ namespace ams::kern::svc { } Result ReadDebugProcessMemory(uintptr_t buffer, ams::svc::Handle debug_handle, uintptr_t address, size_t size) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Validate address / size. */ R_UNLESS(size > 0, svc::ResultInvalidSize()); R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); @@ -306,6 +320,9 @@ namespace ams::kern::svc { } Result GetDebugThreadParam(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index e9153edbb..ec41ef59a 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -314,6 +314,19 @@ namespace ams::kern::svc { *out = io_region->GetHint(); } break; + case ams::svc::InfoType_TransferMemoryHint: + { + /* Verify the sub-type is valid. */ + R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); + + /* Get the transfer memory from its handle. */ + KScopedAutoObject transfer_memory = GetCurrentProcess().GetHandleTable().GetObject(handle); + R_UNLESS(transfer_memory.IsNotNull(), svc::ResultInvalidHandle()); + + /* Get the transfer memory's address hint. */ + *out = transfer_memory->GetHint(); + } + break; case ams::svc::InfoType_MesosphereMeta: { /* Verify the handle is invalid. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp index fc5414905..e2237877d 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp @@ -48,10 +48,11 @@ namespace ams::kern::svc { Result MapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress()); - R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); - R_UNLESS(size > 0, svc::ResultInvalidSize()); - R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); + const size_t min_alignment = Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool()); + R_UNLESS(util::IsAligned(address, min_alignment), svc::ResultInvalidAddress()); + R_UNLESS(util::IsAligned(size, min_alignment), svc::ResultInvalidSize()); + R_UNLESS(size > 0, svc::ResultInvalidSize()); + R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); @@ -69,10 +70,11 @@ namespace ams::kern::svc { Result UnmapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress()); - R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); - R_UNLESS(size > 0, svc::ResultInvalidSize()); - R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); + const size_t min_alignment = Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool()); + R_UNLESS(util::IsAligned(address, min_alignment), svc::ResultInvalidAddress()); + R_UNLESS(util::IsAligned(size, min_alignment), svc::ResultInvalidSize()); + R_UNLESS(size > 0, svc::ResultInvalidSize()); + R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 76e36302b..6e516a51f 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -71,6 +71,9 @@ namespace ams::kern::svc { } Result GetProcessList(int32_t *out_num_processes, KUserPointer out_process_ids, int32_t max_out_count) { + /* Only allow invoking the svc on development hardware. */ + R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented()); + /* Validate that the out count is valid. */ R_UNLESS((0 <= max_out_count && max_out_count <= static_cast(std::numeric_limits::max() / sizeof(u64))), svc::ResultOutOfRange()); @@ -106,12 +109,13 @@ namespace ams::kern::svc { /* Decide on an address space map region. */ uintptr_t map_start, map_end; size_t map_size; + const size_t code_size = params.code_num_pages * PageSize; switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) { case ams::svc::CreateProcessFlag_AddressSpace32Bit: case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: { - map_start = KAddressSpaceInfo::GetAddressSpaceStart(32, KAddressSpaceInfo::Type_MapSmall); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(32, KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -120,8 +124,8 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(36, KAddressSpaceInfo::Type_MapSmall); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(36, KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -130,10 +134,10 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(39, KAddressSpaceInfo::Type_Map39Bit); - map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Map39Bit); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit, code_size); + map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Heap); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); } break; default: @@ -178,7 +182,6 @@ namespace ams::kern::svc { const size_t code_num_pages = params.code_num_pages; const size_t system_resource_num_pages = params.system_resource_num_pages; const size_t total_pages = code_num_pages + system_resource_num_pages; - const size_t code_size = code_num_pages * PageSize; const size_t system_resource_size = system_resource_num_pages * PageSize; const size_t total_size = code_size + system_resource_size; @@ -293,7 +296,9 @@ namespace ams::kern::svc { Result StartProcess(ams::svc::Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size) { /* Validate stack size. */ - R_UNLESS(main_thread_stack_size == static_cast(main_thread_stack_size), svc::ResultOutOfMemory()); + const uint64_t aligned_stack_size = util::AlignUp(main_thread_stack_size, Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool())); + R_UNLESS(aligned_stack_size >= main_thread_stack_size, svc::ResultOutOfMemory()); + R_UNLESS(aligned_stack_size == static_cast(aligned_stack_size), svc::ResultOutOfMemory()); /* Get the target process. */ KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject(process_handle); @@ -311,7 +316,7 @@ namespace ams::kern::svc { process->SetIdealCoreId(core_id); /* Run the process. */ - R_RETURN(process->Run(priority, static_cast(main_thread_stack_size))); + R_RETURN(process->Run(priority, static_cast(aligned_stack_size))); } Result TerminateProcess(ams::svc::Handle process_handle) { diff --git a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp index 91d799d78..41420ca06 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp @@ -27,6 +27,7 @@ namespace ams::kern::svc { case ams::svc::MemoryPermission_Read: case ams::svc::MemoryPermission_ReadWrite: case ams::svc::MemoryPermission_ReadExecute: + case ams::svc::MemoryPermission_Execute: return true; default: return false; diff --git a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp index 99c8c37a8..6f74dd145 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp @@ -217,6 +217,9 @@ namespace ams::kern::svc { } Result GetThreadList(int32_t *out_num_threads, KUserPointer out_thread_ids, int32_t max_out_count, ams::svc::Handle debug_handle) { + /* Only allow invoking the svc on development hardware. */ + R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented()); + /* Validate that the out count is valid. */ R_UNLESS((0 <= max_out_count && max_out_count <= static_cast(std::numeric_limits::max() / sizeof(u64))), svc::ResultOutOfRange()); @@ -225,30 +228,34 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory()); } - if (debug_handle == ams::svc::InvalidHandle) { - /* If passed invalid handle, we should return the global thread list. */ - R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count)); + /* Get the handle table. */ + auto &handle_table = GetCurrentProcess().GetHandleTable(); + + /* Try to get as a debug object. */ + KScopedAutoObject debug = handle_table.GetObject(debug_handle); + if (debug.IsNotNull()) { + /* Check that the debug object has a process. */ + R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated()); + R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated()); + ON_SCOPE_EXIT { debug->CloseProcess(); }; + + /* Get the thread list. */ + R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); } else { - /* Get the handle table. */ - auto &handle_table = GetCurrentProcess().GetHandleTable(); - - /* Try to get as a debug object. */ - KScopedAutoObject debug = handle_table.GetObject(debug_handle); - if (debug.IsNotNull()) { - /* Check that the debug object has a process. */ - R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated()); - R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated()); - ON_SCOPE_EXIT { debug->CloseProcess(); }; - - /* Get the thread list. */ - R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); - } else { - /* Try to get as a process. */ - KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle(debug_handle); - R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); + /* Only allow getting as a process (or global) if the caller does not have ForceDebugProd. */ + R_UNLESS(!GetCurrentProcess().CanForceDebugProd(), svc::ResultInvalidHandle()); + /* Try to get as a process. */ + KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle(debug_handle); + if (process.IsNotNull()) { /* Get the thread list. */ R_TRY(process->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); + } else { + /* If the object is not a process, the caller may want the global thread list. */ + R_UNLESS(debug_handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle()); + + /* If passed invalid handle, we should return the global thread list. */ + R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count)); } } diff --git a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp index cd20d43a7..ca1c5cb5d 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -95,7 +95,7 @@ namespace ams::impl { AMS_DEFINE_SYSTEM_THREAD(16, creport, Main); /* ro. */ - AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); + AMS_DEFINE_SYSTEM_THREAD(21, ro, Main); /* gpio. */ AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler); @@ -171,6 +171,8 @@ namespace ams::impl { AMS_DEFINE_SYSTEM_THREAD(21, TioServer, FileServerHtcsServer); AMS_DEFINE_SYSTEM_THREAD(21, TioServer, SdCardObserver); + AMS_DEFINE_SYSTEM_THREAD(16, memlet, Main); + /* ServiceProfile */ AMS_DEFINE_SYSTEM_THREAD(-1, sprofile, IpcServer); diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp index 146b17dd5..a103aae83 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp @@ -50,7 +50,7 @@ namespace ams::ddsf { } void DetachDevice() { - AMS_ASSERT(this->IsOpen()); + /* AMS_ASSERT(this->IsOpen()); */ m_device = nullptr; m_access_mode = AccessMode_None; AMS_ASSERT(!this->IsOpen()); diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index 92d6db7dc..c4dd26ea8 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -81,8 +81,8 @@ HANDLER(NetworkErrorInfo, 40 ) \ HANDLER(FileAccessPathInfo, 41 ) \ HANDLER(GameCardCIDInfo, 42 ) \ - HANDLER(NANDCIDInfo, 43 ) \ - HANDLER(MicroSDCIDInfo, 44 ) \ + HANDLER(NANDCIDInfoDeprecated, 43 ) \ + HANDLER(MicroSDCIDInfoDeprecated, 44 ) \ HANDLER(NANDSpeedModeInfo, 45 ) \ HANDLER(MicroSDSpeedModeInfo, 46 ) \ HANDLER(GameCardSpeedModeInfo, 47 ) \ @@ -112,7 +112,7 @@ HANDLER(FocusedAppletHistoryInfo, 71 ) \ HANDLER(CompositorInfo, 72 ) \ HANDLER(BatteryChargeInfo, 73 ) \ - HANDLER(NANDExtendedCsd, 74 ) \ + HANDLER(NANDExtendedCsdDeprecated, 74 ) \ HANDLER(NANDPatrolInfo, 75 ) \ HANDLER(NANDErrorInfo, 76 ) \ HANDLER(NANDDriverLog, 77 ) \ @@ -178,9 +178,19 @@ HANDLER(BuiltInWirelessOUIInfo, 137 ) \ HANDLER(WirelessAPOUIInfo, 138 ) \ HANDLER(EthernetAdapterOUIInfo, 139 ) \ - HANDLER(NANDTypeInfo, 140 ) \ + HANDLER(NANDTypeInfoDeprecated, 140 ) \ HANDLER(MicroSDTypeInfo, 141 ) \ - HANDLER(TestNx, 1000) + HANDLER(AttachmentFileInfo, 142 ) \ + HANDLER(WlanInfo, 143 ) \ + HANDLER(HalfAwakeStateInfo, 144 ) \ + HANDLER(PctlSettingInfo, 145 ) \ + HANDLER(GameCardLogInfo, 146 ) \ + HANDLER(WlanIoctlErrorInfo, 147 ) \ + HANDLER(SdCardActivationInfo, 148 ) \ + HANDLER(GameCardDetailedErrorInfo, 149 ) \ + HANDLER(TestNx, 1000) \ + HANDLER(NANDTypeInfo, 1001) \ + HANDLER(NANDExtendedCsd, 1002) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ @@ -280,8 +290,8 @@ 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(NANDCIDDeprecated, 97, NANDCIDInfoDeprecated, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCIDDeprecated, 98, MicroSDCIDInfoDeprecated, 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 ) \ @@ -339,7 +349,7 @@ 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(LastDvfsThresholdTrippedDeprecated, 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 ) \ @@ -373,9 +383,9 @@ HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(OtgRequestedDeprecated, 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(NANDPreEolInfoDeprecated, 190, NANDExtendedCsdDeprecated, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypADeprecated, 191, NANDExtendedCsdDeprecated, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypBDeprecated, 192, NANDExtendedCsdDeprecated, 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 ) \ @@ -445,22 +455,22 @@ HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionReasonDeprecated, 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(OscillatorClockDeprecated, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocksDeprecated, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltagesDeprecated, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltagesDeprecated, 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(ModuleClockEnableFlagsDeprecated, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlagsDeprecated, 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(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltagesDeprecated, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(FuseInfoDeprecated, 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 ) \ @@ -723,7 +733,7 @@ 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(DramIdDeprecated, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ @@ -830,9 +840,9 @@ HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCountDeprecated, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCountDeprecated, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCountDeprecated, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ @@ -860,11 +870,62 @@ HANDLER(FatFsBisUserFatErrorNumber, 674, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FatFsBisUserFatSafeErrorNumber, 675, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(GpuCrashDump2, 676, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDType, 677, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDTypeDeprecated, 677, NANDTypeInfoDeprecated, FieldType_U8Array, FieldFlag_None ) \ HANDLER(MicroSDType, 678, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(GameCardLastDeactivateReasonResult, 679, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(GameCardLastDeactivateReason, 680, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(InvalidErrorCode, 681, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletId, 682, ApplicationInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PrevReportIdentifier, 683, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(SyslogStartupTimeBase, 684, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NxdmpIsAttached, 685, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ScreenshotIsAttached, 686, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SyslogIsAttached, 687, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SaveSyslogResult, 688, AttachmentFileInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EncryptionKeyGeneration, 689, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FsBufferManagerNonBlockingRetriedCount, 690, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferNonBlockingRetriedCount, 691, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GpuCrashDumpAttachmentId, 695, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GpuCrashDumpIsAttached, 696, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallerIdentifier, 697, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(WlanMainState, 698, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(WlanSubState, 699, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AdspSyslogIsAttached, 702, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTime, 703, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTimeAfterBackgroundTaskDone, 704, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTimeAfterStateUnlocked, 705, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakePowerStateMessage, 706, HalfAwakeStateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastlyRequestId, 707, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CloudflareCfRay, 708, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WlanCommandEventHistory, 709, WlanInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsSaveDataAttributeCheckFailureCount, 710, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlIsRestrictionEnabled, 711, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsPairingActive, 712, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlSafetyLevel, 713, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlRatingAge, 714, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlRatingOrganization, 715, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlIsSnsPostRestricted, 716, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsFreeCommunicationRestrictedByDefault, 717, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsStereoVisionRestricted, 718, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlRestrictedFreeCommunicationApplicationIdList, 719, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(PctlExemptApplicationIdList, 720, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(GameCardLogEncryptionKeyIndex, 721, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLogEncryptedKey, 722, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicHandlerLogLength, 723, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardWorkerLogLength, 724, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicHandlerLogTimeStamp, 725, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardWorkerLogTimeStamp, 726, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardEncryptedAsicHandlerLog, 727, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardEncryptedWorkerLog, 728, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(WlanIoctlErrno, 729, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FsSaveDataCertificateVerificationFailureCount, 730, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(SdCardActivationMilliSeconds, 731, SdCardActivationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardPreviousInsertedTimestamp, 734, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -877,5 +938,26 @@ HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) + HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 1013, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 1014, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 1015, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 1016, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 1017, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 1018, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 1019, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 1020, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(FuseInfo, 1021, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(NANDType, 1022, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 1023, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 1024, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 1025, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 1029, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DramId, 1030, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp index 784bcc9da..a4fcc4dc6 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp @@ -20,26 +20,28 @@ #include #include -#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ - AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) +#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp index e8ed06310..e75bfb341 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp @@ -17,13 +17,16 @@ #include #include -#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out out), (out), hos::Version_5_0_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentList, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0) +#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out out), (out), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentListDeprecated, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0, hos::Version_19_0_1) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, GetAttachmentList, (ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_count, out_buf, report_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, GetReportSizeMax, (ams::sf::Out out), (out), hos::Version_20_0_0) + AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F) diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp index dd5e5b33d..1bc47d4b2 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp @@ -21,9 +21,9 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: 16.2.0.0 */ - Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); - Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific); - Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific); + Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index f5373ac8d..7a2778a9e 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -150,7 +150,8 @@ namespace ams::fssrv { Result OpenCodeFileSystemDeprecated(ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id); Result OpenCodeFileSystemDeprecated2(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id); Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); Result IsArchivedProgram(ams::sf::Out out, u64 process_id); }; static_assert(sf::IsIFileSystemProxy); @@ -174,11 +175,16 @@ namespace ams::fssrv { R_THROW(fs::ResultPortAcceptableCountLimited()); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_UNUSED(out_fs, out_verif, path, attr, program_id); R_THROW(fs::ResultPortAcceptableCountLimited()); } + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id); + R_THROW(fs::ResultPortAcceptableCountLimited()); + } + Result IsArchivedProgram(ams::sf::Out out, u64 process_id) { AMS_UNUSED(out, process_id); R_THROW(fs::ResultPortAcceptableCountLimited()); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp index 488b49639..0e55e2562 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp @@ -21,12 +21,13 @@ #include /* ACCURATE_TO_VERSION: 17.5.0.0 */ -#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) +#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated4, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0, hos::Version_19_0_1) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id), (out_fs, out_verif, attr, program_id, storage_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IFileSystemProxyForLoader, AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO, 0xDC92EE15) diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp index 90f2ccdb0..17dfb656b 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp @@ -16,7 +16,7 @@ #pragma once #include #include -#include +#include namespace ams::fssystem { @@ -26,10 +26,10 @@ namespace ams::fssystem { void InvalidateHardwareAesKey(); - bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation); + bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation); - const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused); - size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused); + const u8 *GetAcidSignatureKeyModulus(ncm::ContentMetaPlatform platform, bool prod, size_t key_generation, bool unk_unused); + size_t GetAcidSignatureKeyModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused); const u8 *GetAcidSignatureKeyPublicExponent(); diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 597cc0876..66be2b66a 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -83,7 +83,12 @@ namespace ams::hos { Version_17_0_0 = ::ams::TargetFirmware_17_0_0, Version_17_0_1 = ::ams::TargetFirmware_17_0_1, Version_18_0_0 = ::ams::TargetFirmware_18_0_0, + Version_18_0_1 = ::ams::TargetFirmware_18_0_1, Version_18_1_0 = ::ams::TargetFirmware_18_1_0, + Version_19_0_0 = ::ams::TargetFirmware_19_0_0, + Version_19_0_1 = ::ams::TargetFirmware_19_0_1, + Version_20_0_0 = ::ams::TargetFirmware_20_0_0, + Version_20_0_1 = ::ams::TargetFirmware_20_0_1, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp index 651b25bff..39c0bc3da 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp @@ -19,14 +19,14 @@ #include #include -#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h), (proc_h, id, flags, std::move(reslimit_h))) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ - AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \ - AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) +#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ldr::ProgramAttributes &attrs), (proc_h, id, flags, std::move(reslimit_h), attrs)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, loc, attrs)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ + AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ + AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, out_status, loc, attrs)) \ + AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) AMS_SF_DEFINE_INTERFACE(ams::ldr::impl, IProcessManagerInterface, AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO, 0x01518B8E) diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp index dd5d34b9a..310c6fa51 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp @@ -20,15 +20,15 @@ namespace ams::ldr::pm { /* Process Manager API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit); - Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit, ldr::ProgramAttributes attrs); + Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result UnpinProgram(PinId pin_id); Result SetEnabledProgramVerification(bool enabled); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); /* Atmosphere extension API. */ - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); } diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 325d2a35d..5cc2fbb8b 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include namespace ams::ldr { @@ -34,9 +35,10 @@ namespace ams::ldr { u32 aci_sac_size; u32 acid_fac_size; u32 aci_fah_size; + u8 unused_20[0x10]; u8 ac_buffer[0x3E0]; }; - static_assert(util::is_pod::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!"); + static_assert(util::is_pod::value && sizeof(ProgramInfo) == 0x410, "ProgramInfo definition!"); enum ProgramInfoFlag { ProgramInfoFlag_SystemModule = (0 << 0), @@ -226,6 +228,7 @@ namespace ams::ldr { MetaFlag_OptimizeMemoryAllocation = (1 << 4), MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5), MetaFlag_EnableAliasRegionExtraSize = (1 << 6), + MetaFlag_PreventCodeReads = (1 << 7), }; enum AddressSpaceType { @@ -263,4 +266,10 @@ namespace ams::ldr { }; static_assert(sizeof(Npdm) == 0x80 && util::is_pod::value, "Npdm definition!"); + struct ProgramAttributes { + ncm::ContentMetaPlatform platform; + fs::ContentAttributes content_attributes; + }; + static_assert(sizeof(ProgramAttributes) == 2 && util::is_pod::value, "ProgramAttributes definition!"); + } diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp index fde547802..6c6a8adec 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp @@ -226,6 +226,11 @@ namespace ams::ncm { AMS_ASSERT(m_interface != nullptr); R_RETURN(m_interface->GetPlatform(out, key)); } + + Result HasAttributes(u8 *out, u8 attr_mask) { + AMS_ASSERT(m_interface != nullptr); + R_RETURN(m_interface->HasAttributes(out, attr_mask)); + } }; } diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp index dc693875a..f8888e49f 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp @@ -282,7 +282,7 @@ namespace ams::ncm { } const FragmentSet *GetFragmentSet(s32 delta_index, s32 fragment_set_index) const { - return reinterpret_cast(this->GetFragmentSetIndex(delta_index, fragment_set_index)); + return reinterpret_cast(this->GetFragmentSetAddress(delta_index, fragment_set_index)); } const FragmentIndicator *GetFragmentIndicator(s32 delta_index, s32 fragment_set_index, s32 index) const { diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp index 099de50fb..39c04cd03 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp @@ -44,7 +44,8 @@ AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \ AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \ AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \ - AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) + AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 27, Result, HasAttributes, (sf::Out out, u8 attr_mask), (out, attr_mask), hos::Version_20_0_0) AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp index 38bfc154f..8d0e79ff0 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp @@ -72,6 +72,7 @@ namespace ams::ncm { Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type); Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset); Result GetPlatform(sf::Out out, const ContentMetaKey &key); + Result HasAttributes(sf::Out out, u8 attr_mask); }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp index b02c38fc5..b8e7bcd41 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp @@ -121,13 +121,15 @@ namespace ams::ncm { static const AtmosphereProgramId Mitm; static const AtmosphereProgramId AtmosphereLogManager; + static const AtmosphereProgramId AtmosphereMemlet; }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul }; + inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereMemlet = { 0x0100000000000421ul }; inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) { - return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager; + return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager || program_id == AtmosphereProgramId::AtmosphereMemlet; } inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &) { diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp index a34f2272d..66faf57e2 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp @@ -19,8 +19,10 @@ #include #include -#define AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, void, GetBootMode, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 1, void, SetMaintenanceBoot, (), ()) +#define AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, void, GetBootMode, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, void, SetMaintenanceBoot, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 2, void, GetUnknown, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, SetUnknown, (u32 val), (val)) AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IBootModeInterface, AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO, 0x96D01649) diff --git a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp index 886b771da..4a1ce2684 100644 --- a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp @@ -135,14 +135,15 @@ namespace ams::ro { class NroHeader { public: static constexpr u32 Magic = util::FourCC<'N','R','O','0'>::Code; + static constexpr u32 FlagAlignedHeader = 1; private: u32 m_entrypoint_insn; u32 m_mod_offset; u8 m_reserved_08[0x8]; u32 m_magic; - u8 m_reserved_14[0x4]; + u8 m_version; u32 m_size; - u8 m_reserved_1C[0x4]; + u32 m_flags; u32 m_text_offset; u32 m_text_size; u32 m_ro_offset; @@ -158,10 +159,22 @@ namespace ams::ro { return m_magic == Magic; } + u32 GetVersion() const { + return m_version; + } + u32 GetSize() const { return m_size; } + u32 GetFlags() const { + return m_flags; + } + + bool IsAlignedHeader() const { + return m_flags & FlagAlignedHeader; + } + u32 GetTextOffset() const { return m_text_offset; } diff --git a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index b724ce5f1..d68a56f33 100644 --- a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp +++ b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp @@ -231,7 +231,7 @@ R_RETURN(::svcGetThreadContext3(reinterpret_cast<::ThreadContext *>(out_context.GetPointerUnsafe()), thread_handle)); } - ALWAYS_INLINE Result WaitForAddress(::ams::svc::Address address, ::ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + ALWAYS_INLINE Result WaitForAddress(::ams::svc::Address address, ::ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(::svcWaitForAddress(reinterpret_cast(static_cast(address)), arb_type, value, timeout_ns)); } diff --git a/libraries/libstratosphere/libstratosphere.mk b/libraries/libstratosphere/libstratosphere.mk index b10f27f13..faec4fdb3 100644 --- a/libraries/libstratosphere/libstratosphere.mk +++ b/libraries/libstratosphere/libstratosphere.mk @@ -154,12 +154,14 @@ spl_secure_monitor_api.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/l fs_id_string_impl.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/include ifeq ($(ATMOSPHERE_OS_NAME),windows) -# I do not remember why these had fno-lto, but it appears to -# work without no-lto (2023/03/09), so I am disabling these. I may regret this later. -#os_%.o: CXXFLAGS += -fno-lto -#fssystem_%.o: CXXFLAGS += -fno-lto -#fssrv_%.o: CXXFLAGS += -fno-lto -#fs_%.o: CXXFLAGS += -fno-lto +# Audit builds fail when these have lto disabled. +# Noting 10/29/24: +# In member function '__ct ': +# internal compiler error: in binds_to_current_def_p, at symtab.cc:2589 +os_%.o: CXXFLAGS += -fno-lto +fssystem_%.o: CXXFLAGS += -fno-lto +fssrv_%.o: CXXFLAGS += -fno-lto +fs_%.o: CXXFLAGS += -fno-lto endif #--------------------------------------------------------------------------------- diff --git a/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp b/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp index e5f27fce6..5f7f296a6 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp @@ -450,6 +450,9 @@ namespace ams::boot2 { LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Migration, ncm::StorageId::BuiltInSystem), 0); } + /* Launch atmosphere's applet memory service program. */ + LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::AtmosphereProgramId::AtmosphereMemlet, ncm::StorageId::None), 0); + /* Launch user programs off of the SD. */ LaunchFlaggedProgramsOnSdCard(); } diff --git a/libraries/libstratosphere/source/diag/diag_log_impl.hpp b/libraries/libstratosphere/source/diag/diag_log_impl.hpp index 05b625307..4a504375f 100644 --- a/libraries/libstratosphere/source/diag/diag_log_impl.hpp +++ b/libraries/libstratosphere/source/diag/diag_log_impl.hpp @@ -20,7 +20,7 @@ namespace ams::diag { namespace impl { - constexpr inline size_t DebugPrintBufferLength = 0x80; + constexpr inline size_t DebugPrintBufferLength = 0x100; } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp index 695b12229..77a39a5c5 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp @@ -50,7 +50,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags, nullptr)); ManagerImpl::NotifyAll(); @@ -142,6 +142,11 @@ namespace ams::erpt::srv { R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size)); } + Result ContextImpl::SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) { + /* TODO: Implement LZ4 compression on attachments. */ + R_RETURN(this->SubmitAttachment(out, attachment_name, attachment_data)); + } + Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); @@ -154,7 +159,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags, nullptr)); ManagerImpl::NotifyAll(); @@ -169,6 +174,29 @@ namespace ams::erpt::srv { R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); } + Result ContextImpl::CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id) { + const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); + const u8 *data = reinterpret_cast(data_buffer.GetPointer()); + const ReportMetaData *meta = reinterpret_cast(meta_buffer.GetPointer()); + + const u32 ctx_size = static_cast(ctx_buffer.GetSize()); + const u32 data_size = static_cast(data_buffer.GetSize()); + const u32 meta_size = static_cast(meta_buffer.GetSize()); + + const AttachmentId *attachments = reinterpret_cast(attachment_ids_buffer.GetPointer()); + const u32 num_attachments = attachment_ids_buffer.GetSize() / sizeof(*attachments); + + R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); + R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument()); + R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument()); + + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, attachments, num_attachments, flags, std::addressof(report_id))); + + ManagerImpl::NotifyAll(); + + R_SUCCEED(); + } + Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) { R_RETURN(Reporter::RegisterRunningApplet(program_id)); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp index d6c98c94b..cada2ceb2 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp @@ -35,6 +35,8 @@ namespace ams::erpt::srv { Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags); Result CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result); Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags); + Result SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); + Result CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_data, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id); Result RegisterRunningApplet(ncm::ProgramId program_id); Result UnregisterRunningApplet(ncm::ProgramId program_id); Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp index 0b116f7ba..c41e04f36 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp @@ -86,7 +86,7 @@ namespace ams::erpt::srv { R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str))); /* Create report. */ - R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags())); + R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags(), nullptr)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp index 446ccafca..84dd89f53 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp @@ -51,8 +51,8 @@ namespace ams::erpt::srv { R_RETURN(JournalForReports::DeleteReport(report_id)); } - Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) { - R_RETURN(JournalForAttachments::GetAttachmentList(out, report_id)); + Result Journal::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { + R_RETURN(JournalForAttachments::GetAttachmentList(out_count, out_infos, max_out_infos, report_id)); } util::Uuid Journal::GetJournalId() { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp index 5adfa87c0..16011e75a 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp @@ -82,7 +82,7 @@ namespace ams::erpt::srv { static void CleanupAttachments(); static Result CommitJournal(Stream *stream); static Result DeleteAttachments(ReportId report_id); - static Result GetAttachmentList(AttachmentList *out, ReportId report_id); + static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); static u32 GetUsedStorage(); static Result RestoreJournal(Stream *stream); @@ -99,7 +99,7 @@ namespace ams::erpt::srv { static void CleanupReports(); static Result Commit(); static Result Delete(ReportId report_id); - static Result GetAttachmentList(AttachmentList *out, ReportId report_id); + static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); static util::Uuid GetJournalId(); static s64 GetMaxReportSize(); static Result GetReportList(ReportList *out, ReportType type_filter); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp index 4a7c75570..402951380 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp @@ -77,14 +77,19 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) { + Result JournalForAttachments::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { + if (hos::GetVersion() >= hos::Version_20_0_0) { + /* TODO: What define gives a minimum of 10? */ + R_UNLESS(max_out_infos >= 10, erpt::ResultInvalidArgument()); + } + u32 count = 0; - for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < util::size(out->attachments); it++) { + for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < max_out_infos; it++) { if (report_id == it->m_info.owner_report_id) { - out->attachments[count++] = it->m_info; + out_infos[count++] = it->m_info; } } - out->attachment_count = count; + *out_count = count; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp index 144507e42..2130a5200 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp @@ -86,10 +86,23 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result ManagerImpl::GetAttachmentList(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { + Result ManagerImpl::GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument()); - R_RETURN(Journal::GetAttachmentList(reinterpret_cast(out_list.GetPointer()), report_id)); + auto *attachment_list = reinterpret_cast(out_list.GetPointer()); + + R_RETURN(Journal::GetAttachmentList(std::addressof(attachment_list->attachment_count), attachment_list->attachments, util::size(attachment_list->attachments), report_id)); + } + + Result ManagerImpl::GetAttachmentList(ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id) { + R_RETURN(Journal::GetAttachmentList(out_count.GetPointer(), reinterpret_cast(out_buf.GetPointer()), out_buf.GetSize() / sizeof(AttachmentInfo), report_id)); + } + + Result ManagerImpl::GetReportSizeMax(ams::sf::Out out) { + /* TODO: Where is this size defined? */ + constexpr size_t ReportSizeMax = 0x3FF4F; + *out = ReportSizeMax; + R_SUCCEED(); } } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp index bbf0c254e..24046b29b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp @@ -34,7 +34,9 @@ namespace ams::erpt::srv { Result CleanupReports(); Result DeleteReport(const ReportId &report_id); Result GetStorageUsageStatistics(ams::sf::Out out); - Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetAttachmentList(ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetReportSizeMax(ams::sf::Out out); }; static_assert(erpt::sf::IsIManager); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index 274f9d5ab..a9a2871c6 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -414,7 +414,7 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) { /* Create a context record for the report. */ auto record = std::make_unique(); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); @@ -423,10 +423,10 @@ namespace ams::erpt::srv { R_TRY(record->Initialize(ctx, data, data_size)); /* Create the report. */ - R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags)); + R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags, specified_report_id)); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) { /* Clear the automatic categories, when we're done with our report. */ ON_SCOPE_EXIT { Context::ClearContext(CategoryId_ErrorInfo); @@ -444,7 +444,7 @@ namespace ams::erpt::srv { R_TRY(SubmitReportDefaults(ctx)); /* Generate report id. */ - const ReportId report_id = { .uuid = util::GenerateUuid() }; + const ReportId report_id = specified_report_id ? *specified_report_id : ReportId{ .uuid = util::GenerateUuid() }; /* Get posix timestamps. */ time::PosixTime timestamp_user; @@ -537,6 +537,8 @@ namespace ams::erpt::srv { /* NOTE: Nintendo ignores the result of this call. */ SubmitFsInfo(); } + #else + AMS_UNUSED(flags); #endif diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp index 11913dbd5..f5db475ec 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp @@ -58,8 +58,8 @@ namespace ams::erpt::srv { private: static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp, erpt::CreateReportOptionFlagSet flags); public: - static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); - static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); + static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id); + static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id); }; } diff --git a/libraries/libstratosphere/source/fs/fs_code.cpp b/libraries/libstratosphere/source/fs/fs_code.cpp index a8015cd6a..e7c694e0f 100644 --- a/libraries/libstratosphere/source/fs/fs_code.cpp +++ b/libraries/libstratosphere/source/fs/fs_code.cpp @@ -69,7 +69,7 @@ namespace ams::fs { return GetReference(g_stratosphere_romfs_fs); } - Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { /* Print a path suitable for the remote service. */ fssrv::sf::Path sf_path; R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path)); @@ -79,7 +79,11 @@ namespace ams::fs { R_TRY(fsp->SetCurrentProcess({})); sf::SharedPointer fs; - R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id)); + if (hos::GetVersion() >= hos::Version_20_0_0) { + R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), attr, program_id, storage_id)); + } else { + R_TRY(fsp->OpenCodeFileSystemDeprecated4(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id)); + } /* Allocate a new filesystem wrapper. */ auto fsa = std::make_unique(std::move(fs)); @@ -148,7 +152,7 @@ namespace ams::fs { R_SUCCEED(); } - Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { /* If we can open an sd card code fs, use it. */ R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id))); @@ -156,7 +160,7 @@ namespace ams::fs { R_SUCCEED_IF(R_SUCCEEDED(OpenStratosphereCodeFileSystemImpl(out, program_id))); /* Otherwise, fall back to a normal code fs. */ - R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id)); + R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id, storage_id)); } Result OpenHblCodeFileSystemImpl(std::unique_ptr *out) { @@ -334,11 +338,12 @@ namespace ams::fs { util::optional m_code_fs; util::optional m_hbl_fs; ncm::ProgramId m_program_id; + ncm::StorageId m_storage_id; bool m_initialized; public: AtmosphereCodeFileSystem() : m_initialized(false) { /* ... */ } - Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { + Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) { AMS_ABORT_UNLESS(!m_initialized); /* If we're hbl, we need to open a hbl fs. */ @@ -350,10 +355,11 @@ namespace ams::fs { /* Open the code filesystem. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id, storage_id)); m_code_fs.emplace(std::move(fsa), program_id, is_specific); - m_program_id = program_id; + m_program_id = program_id; + m_storage_id = storage_id; m_initialized = true; R_SUCCEED(); @@ -386,7 +392,7 @@ namespace ams::fs { } - Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -399,7 +405,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); /* Register. */ R_RETURN(fsa::Register(name, std::move(fsa))); @@ -414,7 +420,7 @@ namespace ams::fs { R_SUCCEED(); } - Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { + Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -430,7 +436,7 @@ namespace ams::fs { R_UNLESS(ams_code_fs != nullptr, fs::ResultAllocationMemoryFailedInCodeA()); /* Initialize the code file system. */ - R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, is_hbl, is_specific)); + R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, storage_id, is_hbl, is_specific)); /* Register. */ R_RETURN(fsa::Register(name, std::move(ams_code_fs))); @@ -445,7 +451,7 @@ namespace ams::fs { R_SUCCEED(); } - Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -458,7 +464,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); /* Create a wrapper fs. */ auto wrap_fsa = std::make_unique(std::move(fsa), program_id, false); diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp index 71edaeb4f..528b1a92b 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp @@ -33,7 +33,7 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated(ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) { ::FsCodeInfo dummy; ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); @@ -41,7 +41,7 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated2(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); @@ -49,15 +49,23 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + + out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); + R_SUCCEED(); + } + + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + ::FsFileSystem fs; + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, static_cast<::NcmStorageId>(static_cast(storage_id)), nullptr, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); diff --git a/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp b/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp index fc867aeb6..d488fdc93 100644 --- a/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp +++ b/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp @@ -33,14 +33,14 @@ namespace ams::fs { } ALWAYS_INLINE ScopedSetter(ScopedSetter &&rhs) { - m_ptr = rhs.ptr; - m_value = rhs.value; + m_ptr = rhs.m_ptr; + m_value = rhs.m_value; rhs.Reset(); } ALWAYS_INLINE ScopedSetter &operator=(ScopedSetter &&rhs) { - m_ptr = rhs.ptr; - m_value = rhs.value; + m_ptr = rhs.m_ptr; + m_value = rhs.m_value; rhs.Reset(); return *this; } diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index 091b19d3a..15dc8c246 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_18_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_20_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -41,7 +41,9 @@ namespace ams::fs::impl { case KeyGeneration_15_0_0: return "15.0.0-15.0.1"; case KeyGeneration_16_0_0: return "16.0.0-16.0.3"; case KeyGeneration_17_0_0: return "17.0.0-17.0.1"; - case KeyGeneration_18_0_0: return "18.0.0-"; + case KeyGeneration_18_0_0: return "18.0.0-18.1.0"; + case KeyGeneration_19_0_0: return "19.0.0-19.0.1"; + case KeyGeneration_20_0_0: return "20.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index 39b784d52..a22a2d888 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -482,11 +482,16 @@ namespace ams::fssrv { AMS_UNUSED(out_fs, out_verif, path, attr, program_id); } - Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_ABORT("TODO"); AMS_UNUSED(out_fs, out_verif, path, attr, program_id); } + Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + AMS_ABORT("TODO"); + AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id); + } + Result FileSystemProxyImpl::IsArchivedProgram(ams::sf::Out out, u64 process_id) { AMS_ABORT("TODO"); AMS_UNUSED(out, process_id); diff --git a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp index dbd2f86cd..23e4d0b3b 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp @@ -297,20 +297,20 @@ namespace ams::fssystem { } } - bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation) { + bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation) { switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: return key_generation <= NxAcidSignatureKeyGenerationMax; AMS_UNREACHABLE_DEFAULT_CASE(); } } - const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused) { + const u8 *GetAcidSignatureKeyModulus(ncm::ContentMetaPlatform platform, bool prod, size_t key_generation, bool unk_unused) { AMS_ASSERT(IsValidSignatureKeyGeneration(platform, key_generation)); AMS_UNUSED(unk_unused); switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: { const size_t used_keygen = (key_generation % (NxAcidSignatureKeyGenerationMax + 1)); return prod ? NxAcidSignatureKeyModulusProd[used_keygen] : NxAcidSignatureKeyModulusDev[used_keygen]; @@ -319,11 +319,11 @@ namespace ams::fssystem { } } - size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused) { + size_t GetAcidSignatureKeyModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { AMS_UNUSED(unk_unused); switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: return NxAcidSignatureKeyModulusSize; AMS_UNREACHABLE_DEFAULT_CASE(); } diff --git a/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp b/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp index 2a11b1550..0f5760e64 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp @@ -1346,7 +1346,7 @@ namespace ams::fssystem { R_UNLESS(::GetLastError() == ERROR_ACCESS_DENIED, last_error_result); /* Check if we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type is anything other than directory, perform generic result conversion. */ @@ -1459,7 +1459,7 @@ namespace ams::fssystem { R_TRY(this->ResolveFullPath(std::addressof(native_new_path), new_path, MaxFilePathLength, 0, false)); /* Check that the old path is a file. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_old_path.get())); R_UNLESS(type == fs::DirectoryEntryType_File, fs::ResultPathNotFound()); @@ -1509,7 +1509,7 @@ namespace ams::fssystem { R_TRY(this->ResolveFullPath(std::addressof(native_new_path), new_path, MaxDirectoryPathLength, 0, false)); /* Check that the old path is a file. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_old_path.get())); R_UNLESS(type == fs::DirectoryEntryType_Directory, fs::ResultPathNotFound()); @@ -1577,7 +1577,7 @@ namespace ams::fssystem { R_UNLESS(::GetLastError() == ERROR_ACCESS_DENIED, last_error_result); /* Check if we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type isn't file, return path not found. */ @@ -1623,7 +1623,7 @@ namespace ams::fssystem { ON_RESULT_FAILURE { ::CloseHandle(dir_handle); }; /* Check that we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type isn't directory, return path not found. */ diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c index 7d0b4f907..3a0dca194 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c +++ b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c @@ -32,8 +32,14 @@ Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) { return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id); } -Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) { - return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status, +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr) { + const struct { + LoaderProgramAttributes attr; + u16 pad1; + u32 pad2; + NcmProgramLocation loc; + } in = { *attr, 0, 0, *loc }; + return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, in, *out_status, .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize }, .buffers = { { out_program_info, sizeof(*out_program_info) } }, ); diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h index 30a5e4163..b52807112 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h +++ b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h @@ -19,7 +19,7 @@ typedef struct { Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); Result ldrDmntAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); -Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc); +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr); Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status); #ifdef __cplusplus diff --git a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp index 8441977f5..f461f9f7f 100644 --- a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp +++ b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp @@ -19,12 +19,14 @@ namespace ams::ldr::pm { /* Information API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) { - R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, out)); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit, ldr::ProgramAttributes attrs) { + static_assert(sizeof(attrs) == sizeof(::LoaderProgramAttributes)); + R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, reinterpret_cast(std::addressof(attrs)), out)); } - Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) { - R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(out))); + Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) { + static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); + R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(std::addressof(attrs)), reinterpret_cast(out))); } Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) { @@ -40,9 +42,10 @@ namespace ams::ldr::pm { R_RETURN(ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast(program_id))); } - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) { static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); - R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)))); + static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); + R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)), reinterpret_cast(std::addressof(attrs)))); } Result SetEnabledProgramVerification(bool enabled) { diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp index da23ce454..4cf5175b2 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp @@ -534,4 +534,34 @@ namespace ams::ncm { R_SUCCEED(); } + Result ContentMetaDatabaseImpl::HasAttributes(sf::Out out, u8 attribute_mask) { + R_TRY(this->EnsureEnabled()); + + /* Create a variable to hold the combined attributes. */ + u8 combined_attributes = 0; + + /* Iterate over all entries. */ + for (auto &entry : *m_kvs) { + /* Obtain the content meta for the key. */ + const void *meta; + size_t meta_size; + R_TRY(this->GetContentMetaPointer(&meta, &meta_size, entry.GetKey())); + + /* Create a reader. */ + ContentMetaReader reader(meta, meta_size); + + /* Accumulate the set attributes from the current entry. */ + combined_attributes |= (reader.GetHeader()->attributes) & attribute_mask; + + /* If all the attributes we're looking for have been found, we're done. */ + if ((combined_attributes & attribute_mask) == attribute_mask) { + break; + } + } + + /* Set the output. */ + *out = combined_attributes; + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp index 9d6bcfb46..b4e3803d7 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp @@ -65,6 +65,7 @@ namespace ams::ncm { virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) override; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override; virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) override; + virtual Result HasAttributes(sf::Out out, u8 attr_mask) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp index 7c0d57c30..59d6130e9 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp @@ -81,6 +81,7 @@ namespace ams::ncm { virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) = 0; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0; virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) = 0; + virtual Result HasAttributes(sf::Out out, u8 attr_mask) = 0; }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp index b498464cf..148471e86 100644 --- a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp @@ -463,4 +463,28 @@ namespace ams::ncm { })); } + Result IntegratedContentMetaDatabaseImpl::HasAttributes(sf::Out out, u8 attr_mask) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Check that we're enabled. */ + R_TRY(this->EnsureEnabled()); + + /* Test whether we have the attributes on all databases. */ + u8 combined_attributes = 0; + R_TRY(m_list.ForAll([&](const auto &data) { + /* Check the current database. */ + u8 cur_attr = 0; + R_TRY(data.interface->HasAttributes(std::addressof(cur_attr), attr_mask)); + + /* Accumulate the attributes found in the current interface. */ + combined_attributes |= cur_attr; + R_SUCCEED(); + })); + + /* Set the output. */ + *out = combined_attributes; + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp index a0d8a4286..abba78c73 100644 --- a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp @@ -191,6 +191,12 @@ namespace ams::ncm { static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8)); R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast(out.GetPointer()), Convert(key))); } + + Result HasAttributes(sf::Out out, u8 attr_mask) { + /* TODO: libnx bindings */ + AMS_UNUSED(out, attr_mask); + AMS_ABORT(); + } }; static_assert(ncm::IsIContentMetaDatabase); #endif diff --git a/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp index de7b241a6..686cc6995 100644 --- a/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp @@ -27,6 +27,7 @@ namespace ams::os::impl { case os::MemoryPermission_ReadOnly: return svc::MemoryPermission_Read; case os::MemoryPermission_ReadWrite: return svc::MemoryPermission_ReadWrite; case os::MemoryPermission_ReadExecute: return svc::MemoryPermission_ReadExecute; + case os::MemoryPermission_ExecuteOnly: return svc::MemoryPermission_Execute; AMS_UNREACHABLE_DEFAULT_CASE(); } } diff --git a/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp index b336576f1..94450ef26 100644 --- a/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp @@ -43,6 +43,7 @@ namespace ams::os::impl { R_TRY_CATCH(svc::CreateSharedMemory(std::addressof(handle), size, svc_my_perm, svc_other_perm)) { R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles()) R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfResource()) + R_CONVERT(svc::ResultLimitReached, os::ResultOutOfMemory()) } R_END_TRY_CATCH_WITH_ABORT_UNLESS; *out = handle; diff --git a/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp b/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp index 09ec1a8a5..539ceb04f 100644 --- a/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp +++ b/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp @@ -22,7 +22,7 @@ namespace ams::powctl { namespace { impl::SessionImpl &GetOpenSessionImpl(Session &session) { - AMS_ASSERT(session.has_session); + /* AMS_ASSERT(session.has_session); */ auto &impl = GetReference(session.impl_storage); AMS_ASSERT(impl.IsOpen()); return impl; diff --git a/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp b/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp index 51f3b6409..b408bf845 100644 --- a/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp +++ b/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp @@ -22,7 +22,7 @@ namespace ams::powctl { namespace { impl::SessionImpl &GetOpenSessionImpl(Session &session) { - AMS_ASSERT(session.has_session); + /* AMS_ASSERT(session.has_session); */ auto &impl = GetReference(session.impl_storage); AMS_ASSERT(impl.IsOpen()); return impl; diff --git a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp index b4d959b24..a67ae4800 100644 --- a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp +++ b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp @@ -21,7 +21,7 @@ namespace ams::sf::hipc { #if AMS_SF_MITM_SUPPORTED Result ServerManagerBase::InstallMitmServerImpl(os::NativeHandle *out_port_handle, sm::ServiceName service_name, ServerManagerBase::MitmQueryFunction query_func) { /* Install the Mitm. */ - os::NativeHandle query_handle; + os::NativeHandle query_handle = os::InvalidNativeHandle; R_TRY(sm::mitm::InstallMitm(out_port_handle, std::addressof(query_handle), service_name)); /* Register the query handle. */ diff --git a/libraries/libvapours/include/vapours/allocator.hpp b/libraries/libvapours/include/vapours/allocator.hpp index b5d294bfe..3828d4a05 100644 --- a/libraries/libvapours/include/vapours/allocator.hpp +++ b/libraries/libvapours/include/vapours/allocator.hpp @@ -19,7 +19,7 @@ namespace ams { - constexpr inline size_t DefaultAlignment = alignof(max_align_t); + constexpr inline size_t DefaultAlignment = /*alignof(max_align_t)*/ 0x8; using AllocateFunction = void *(*)(size_t); using AllocateFunctionWithUserData = void *(*)(size_t, void *); diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 0e06af0fb..dbd4a2cfe 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 7 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 9 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 18 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 0dde6da81..755fc6387 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -81,9 +81,14 @@ #define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_18_0_1 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_19_0_0 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_19_0_1 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 1) +#define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_20_0_1 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 1) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_1_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_1 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -157,7 +162,12 @@ namespace ams { TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, + TargetFirmware_18_0_1 = ATMOSPHERE_TARGET_FIRMWARE_18_0_1, TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0, + TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_0, + TargetFirmware_19_0_1 = ATMOSPHERE_TARGET_FIRMWARE_19_0_1, + TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0, + TargetFirmware_20_0_1 = ATMOSPHERE_TARGET_FIRMWARE_20_0_1, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, diff --git a/libraries/libvapours/include/vapours/crypto.hpp b/libraries/libvapours/include/vapours/crypto.hpp index 63cfcb2e4..205bbb7e6 100644 --- a/libraries/libvapours/include/vapours/crypto.hpp +++ b/libraries/libvapours/include/vapours/crypto.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp b/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp new file mode 100644 index 000000000..c252263e1 --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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 . + */ + +#pragma once +#include +#include +#include +#include +#include + +namespace ams::crypto { + + class Aes128CmacGenerator { + NON_COPYABLE(Aes128CmacGenerator); + NON_MOVEABLE(Aes128CmacGenerator); + public: + static constexpr size_t MacSize = AesEncryptor128::BlockSize; + private: + AesEncryptor128 m_aes; + CmacGenerator m_cmac_generator; + public: + Aes128CmacGenerator() { /* ... */ } + + void Initialize(const void *key, size_t key_size) { + AMS_ASSERT(key_size == AesEncryptor128::KeySize); + + m_aes.Initialize(key, key_size); + m_cmac_generator.Initialize(std::addressof(m_aes)); + } + + void Update(const void *data, size_t size) { + m_cmac_generator.Update(data, size); + } + + void GetMac(void *dst, size_t size) { + m_cmac_generator.GetMac(dst, size); + } + }; + + ALWAYS_INLINE void GenerateAes128Cmac(void *dst, size_t dst_size, const void *data, size_t data_size, const void *key, size_t key_size) { + Aes128CmacGenerator cmac_generator; + + cmac_generator.Initialize(key, key_size); + cmac_generator.Update(data, data_size); + cmac_generator.GetMac(dst, dst_size); + } + +} diff --git a/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp b/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp new file mode 100644 index 000000000..052dab42e --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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 . + */ + +#pragma once +#include +#include +#include +#include + +namespace ams::crypto { + + template + class CmacGenerator { + NON_COPYABLE(CmacGenerator); + NON_MOVEABLE(CmacGenerator); + private: + using Impl = impl::CmacImpl; + public: + static constexpr size_t MacSize = BlockCipher::BlockSize; + private: + Impl m_impl; + public: + CmacGenerator() { /* ... */ } + + void Initialize(const BlockCipher *cipher) { + return m_impl.Initialize(cipher); + } + + void Update(const void *data, size_t size) { + return m_impl.Update(data, size); + } + + void GetMac(void *dst, size_t dst_size) { + return m_impl.GetMac(dst, dst_size); + } + }; + +} diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp new file mode 100644 index 000000000..fb237540d --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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 . + */ + +#pragma once +#include +#include +#include +#include +#include +#include + +namespace ams::crypto::impl { + + template + class CmacImpl { + NON_COPYABLE(CmacImpl); + NON_MOVEABLE(CmacImpl); + public: + static constexpr size_t BlockSize = BlockCipher::BlockSize; + static constexpr size_t MacSize = BlockSize; + static_assert(BlockSize == 0x10); /* TODO: Should this be supported? */ + private: + enum State { + State_None = 0, + State_Initialized = 1, + State_Done = 2, + }; + private: + CbcMacImpl m_cbc_mac_impl; + u8 m_sub_key[BlockSize]; + State m_state; + public: + CmacImpl() : m_state(State_None) { /* ... */ } + ~CmacImpl() { + /* Clear everything. */ + ClearMemory(this, sizeof(*this)); + } + + void Initialize(const BlockCipher *cipher); + void Update(const void *data, size_t data_size); + void GetMac(void *dst, size_t dst_size); + private: + static void MultiplyOneOverGF128(u8 *data) { + /* Determine the carry bit. */ + const u8 carry = data[0] & 0x80; + + /* Shift all bytes by one bit. */ + for (size_t i = 0; i < BlockSize - 1; ++i) { + data[i] = (data[i] << 1) | (data[i + 1] >> 7); + } + data[BlockSize - 1] <<= 1; + + /* Adjust based on carry. */ + if (carry) { + data[BlockSize - 1] ^= 0x87; + } + } + }; + + template + inline void CmacImpl::Initialize(const BlockCipher *cipher) { + /* Clear the key storage. */ + std::memset(m_sub_key, 0, sizeof(m_sub_key)); + + /* Set the key storage. */ + cipher->EncryptBlock(m_sub_key, BlockSize, m_sub_key, BlockSize); + MultiplyOneOverGF128(m_sub_key); + + /* Initialize the cbc-mac impl. */ + m_cbc_mac_impl.Initialize(cipher); + + /* Mark initialized. */ + m_state = State_Initialized; + } + + template + inline void CmacImpl::Update(const void *data, size_t data_size) { + AMS_ASSERT(m_state == State_Initialized); + + m_cbc_mac_impl.template Update(data, data_size); + } + + template + inline void CmacImpl::GetMac(void *dst, size_t dst_size) { + AMS_ASSERT(m_state == State_Initialized || m_state == State_Done); + AMS_ASSERT(dst_size >= MacSize); + AMS_UNUSED(dst_size); + + /* If we're not already finalized, get the final mac. */ + if (m_state == State_Initialized) { + /* Process padding as needed. */ + if (m_cbc_mac_impl.GetBufferedDataSize() != BlockSize) { + /* Determine the remaining size. */ + const size_t remaining = BlockSize - m_cbc_mac_impl.GetBufferedDataSize(); + + /* Update with padding. */ + static constexpr u8 s_padding[BlockSize] = { 0x80, /* ... */ }; + m_cbc_mac_impl.template Update(s_padding, remaining); + + /* Update our subkey. */ + MultiplyOneOverGF128(m_sub_key); + } + + /* Mask the subkey. */ + m_cbc_mac_impl.MaskBufferedData(m_sub_key, BlockSize); + + /* Set our state as done. */ + m_state = State_Done; + } + + /* Get the mac. */ + m_cbc_mac_impl.GetMac(dst, dst_size); + } + +} diff --git a/libraries/libvapours/include/vapours/results/loader_results.hpp b/libraries/libvapours/include/vapours/results/loader_results.hpp index d9cfa62b5..25e3debee 100644 --- a/libraries/libvapours/include/vapours/results/loader_results.hpp +++ b/libraries/libvapours/include/vapours/results/loader_results.hpp @@ -21,20 +21,20 @@ R_DEFINE_NAMESPACE_RESULT_MODULE(ams::ldr, 9); namespace ams::ldr { - R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1); - R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2); - R_DEFINE_ERROR_RESULT(MetaOverflow, 3); - R_DEFINE_ERROR_RESULT(InvalidMeta, 4); - R_DEFINE_ERROR_RESULT(InvalidNso, 5); - R_DEFINE_ERROR_RESULT(InvalidPath, 6); - R_DEFINE_ERROR_RESULT(MaxProcess, 7); - R_DEFINE_ERROR_RESULT(NotPinned, 8); - R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); - R_DEFINE_ERROR_RESULT(InvalidVersion, 10); - R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); - R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); + R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1); + R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2); + R_DEFINE_ERROR_RESULT(MetaOverflow, 3); + R_DEFINE_ERROR_RESULT(InvalidMeta, 4); + R_DEFINE_ERROR_RESULT(InvalidNso, 5); + R_DEFINE_ERROR_RESULT(InvalidPath, 6); + R_DEFINE_ERROR_RESULT(MaxProcess, 7); + R_DEFINE_ERROR_RESULT(NotPinned, 8); + R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); + R_DEFINE_ERROR_RESULT(InvalidVersion, 10); + R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); + R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); - R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14); + R_DEFINE_ERROR_RESULT(InvalidProgramAttributes, 14); R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51); R_DEFINE_ERROR_RESULT(InvalidNroImage, 52); diff --git a/libraries/libvapours/include/vapours/results/pm_results.hpp b/libraries/libvapours/include/vapours/results/pm_results.hpp index 4c9e51ad5..4e4c0e24b 100644 --- a/libraries/libvapours/include/vapours/results/pm_results.hpp +++ b/libraries/libvapours/include/vapours/results/pm_results.hpp @@ -27,5 +27,6 @@ namespace ams::pm { R_DEFINE_ERROR_RESULT(DebugHookInUse, 4); R_DEFINE_ERROR_RESULT(ApplicationRunning, 5); R_DEFINE_ERROR_RESULT(InvalidSize, 6); + R_DEFINE_ERROR_RESULT(Unknown7, 7); } diff --git a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp index 0f1c57783..7e4121aa3 100644 --- a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp @@ -67,7 +67,7 @@ HANDLER(0x31, Result, GetResourceLimitCurrentValue, OUTPUT(int64_t, out_current_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ HANDLER(0x32, Result, SetThreadActivity, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::ThreadActivity, thread_activity)) \ HANDLER(0x33, Result, GetThreadContext3, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int32_t, value), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int64_t, value), INPUT(int64_t, timeout_ns)) \ HANDLER(0x35, Result, SignalToAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::SignalType, signal_type), INPUT(int32_t, value), INPUT(int32_t, count)) \ HANDLER(0x36, void, SynchronizePreemptionState) \ HANDLER(0x37, Result, GetResourceLimitPeakValue, OUTPUT(int64_t, out_peak_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 5668cd2dd..21ab685d0 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -191,6 +191,8 @@ namespace ams::svc { InfoType_IsSvcPermitted = 26, InfoType_IoRegionHint = 27, InfoType_AliasRegionExtraSize = 28, + /* ... */ + InfoType_TransferMemoryHint = 34, InfoType_MesosphereMeta = 65000, InfoType_MesosphereCurrentProcess = 65001, @@ -261,6 +263,7 @@ namespace ams::svc { ArbitrationType_WaitIfLessThan = 0, ArbitrationType_DecrementAndWaitIfLessThan = 1, ArbitrationType_WaitIfEqual = 2, + ArbitrationType_WaitIfEqual64 = 3, }; enum YieldType : s64 { diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index e7ece762b..4ea900fb7 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,8 +57,8 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(18); - constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20); + constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 5); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); diff --git a/libraries/libvapours/include/vapours/types.hpp b/libraries/libvapours/include/vapours/types.hpp index e7b75a8f0..d22f944ab 100644 --- a/libraries/libvapours/include/vapours/types.hpp +++ b/libraries/libvapours/include/vapours/types.hpp @@ -16,7 +16,6 @@ #pragma once #include #include -#include /* NOTE: This file serves as a substitute for libnx . */ diff --git a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp index 671e49a84..1a2d54846 100644 --- a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp +++ b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp @@ -48,7 +48,7 @@ namespace ams::crypto { " moveq %[result], #1\n" " movne %[result], #0\n" : [result]"=r"(result), [lhs]"+r"(lhs), [rhs]"+r"(rhs), [xor_acc]"=&r"(xor_acc), [index]"=&r"(index), [ltmp]"=&r"(ltmp), [rtmp]"=&r"(rtmp) - : [size]"r"(size) + : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])rhs), [size]"r"(size) : "cc" ); diff --git a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp index 2532415d4..7fdd814d1 100644 --- a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp @@ -47,7 +47,7 @@ namespace ams::crypto { " cmp %w[xor_acc], #0\n" " cset %w[result], eq\n" : [result]"=r"(result), [lhs]"+r"(lhs), [rhs]"+r"(rhs), [xor_acc]"=&r"(xor_acc), [index]"=&r"(index), [ltmp]"=&r"(ltmp), [rtmp]"=&r"(rtmp) - : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])lhs), [size]"r"(size) + : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])rhs), [size]"r"(size) : "cc" ); diff --git a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp index a332d7658..74ff84b47 100644 --- a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp @@ -281,7 +281,7 @@ namespace ams::crypto::impl { [cur_hash0]"+w"(cur_hash0), [cur_hash1]"+w"(cur_hash1), [prev_hash0]"+w"(prev_hash0), [prev_hash1]"+w"(prev_hash1), [tmp_hash]"=w"(tmp_hash), [data]"+r"(data) - : [round_constants]"r"(RoundConstants) + : "m"(*(const u8 (*)[block_count*BlockSize])data), [round_constants]"r"(RoundConstants) : ); } while (--block_count != 0); diff --git a/mesosphere/kernel/kernel.ld b/mesosphere/kernel/kernel.ld index 779488a35..bcd658572 100644 --- a/mesosphere/kernel/kernel.ld +++ b/mesosphere/kernel/kernel.ld @@ -125,6 +125,8 @@ SECTIONS .gnu.version_r : { *(.gnu.version_r) } :rodata .note.gnu.build-id : { *(.note.gnu.build-id) } :rodata + __rodata_end = .; + /* =========== DATA section =========== */ . = ALIGN(0x1000); __data_start = . ; diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index faf34576d..10a000c6d 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -15,6 +15,9 @@ */ #include +extern "C" void __rodata_start(); +extern "C" void __rodata_end(); + extern "C" void __bin_start__(); extern "C" void __bin_end__(); @@ -220,6 +223,31 @@ namespace ams::kern::init { }; static_assert(kern::arch::arm64::init::IsInitialPageAllocator); + void SetupAllTtbr0Entries(KInitialPageTable &init_pt, KInitialPageAllocator &allocator) { + /* Validate that the ttbr0 array is in rodata. */ + const uintptr_t rodata_start = reinterpret_cast(__rodata_start); + const uintptr_t rodata_end = reinterpret_cast(__rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(rodata_start < rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(rodata_start <= reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(0)))); + MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(KPageTable::NumTtbr0Entries))) < rodata_end); + + /* Allocate pages for all ttbr0 entries. */ + for (size_t i = 0; i < KPageTable::NumTtbr0Entries; ++i) { + /* Allocate a page. */ + KPhysicalAddress page = allocator.Allocate(PageSize); + MESOSPHERE_INIT_ABORT_UNLESS(page != Null); + + /* Check that the page is allowed to be a ttbr0 entry. */ + MESOSPHERE_INIT_ABORT_UNLESS((GetInteger(page) & UINT64_C(0xFFFF000000000001)) == 0); + + /* Get the physical address of the ttbr0 entry. */ + const auto ttbr0_phys_ptr = init_pt.GetPhysicalAddress(KVirtualAddress(std::addressof(KPageTable::GetTtbr0Entry(i)))); + + /* Set the entry to the newly allocated page. */ + *reinterpret_cast(GetInteger(ttbr0_phys_ptr)) = (static_cast(i) << 48) | GetInteger(page); + } + } + void FinalizeIdentityMapping(KInitialPageTable &init_pt, KInitialPageAllocator &allocator, u64 phys_to_virt_offset) { /* Create an allocator for identity mapping finalization. */ KInitialPageAllocatorForFinalizeIdentityMapping finalize_allocator(allocator, phys_to_virt_offset); @@ -591,6 +619,9 @@ namespace ams::kern::init { /* Create page table object for use during remaining initialization. */ KInitialPageTable init_pt; + /* Setup all ttbr0 pages. */ + SetupAllTtbr0Entries(init_pt, g_initial_page_allocator); + /* Unmap the identity mapping. */ FinalizeIdentityMapping(init_pt, g_initial_page_allocator, g_phase2_linear_region_phys_to_virt_diff); diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index 5d9084b08..ad483ffc2 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -112,6 +112,14 @@ _ZN3ams4kern4init10StartCore0Emm: #endif 2: /* We're EL1. */ + /* Flush the entire data cache and invalidate the entire TLB. */ + bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv + + /* Invalidate the instruction cache, and ensure instruction consistency. */ + ic ialluis + dsb sy + isb + /* Disable the MMU/Caches. */ bl _ZN3ams4kern4init19DisableMmuAndCachesEv @@ -146,11 +154,15 @@ _ZN3ams4kern4init10StartCore0Emm: /* Save the offset to virtual address from this page's physical address for our use. */ mov x24, x1 + /* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */ + mov x18, #0 + /* At this point kernelldr has been invoked, and we are relocated at a random virtual address. */ /* Next thing to do is to set up our memory management and slabheaps -- all the other core initialization. */ /* Call ams::kern::init::InitializeCore(uintptr_t, void **) */ mov x1, x0 /* Kernelldr returns a state object for the kernel to re-use. */ mov x0, x21 /* Use the address we determined earlier. */ + nop INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase1EmPPv) /* Get the init arguments for core 0. */ @@ -164,6 +176,7 @@ _ZN3ams4kern4init10StartCore0Emm: /* Perform further initialization with the stack pointer set up, as required. */ /* This will include e.g. unmapping the identity mapping. */ + nop INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase2Ev) /* Get the init arguments for core 0. */ @@ -220,6 +233,14 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: #endif 2: /* We're EL1. */ + /* Flush the entire data cache and invalidate the entire TLB. */ + bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv + + /* Invalidate the instruction cache, and ensure instruction consistency. */ + ic ialluis + dsb sy + isb + /* Disable the MMU/Caches. */ bl _ZN3ams4kern4init19DisableMmuAndCachesEv @@ -241,6 +262,7 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: b.eq 3f b 4f 3: /* We're running on a Cortex-A53/Cortex-A57. */ + /* NOTE: Nintendo compares these values instead of setting them, infinite looping on incorrect value. */ ldr x1, [x20, #(INIT_ARGUMENTS_CPUACTLR)] msr cpuactlr_el1, x1 ldr x1, [x20, #(INIT_ARGUMENTS_CPUECTLR)] @@ -265,6 +287,9 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: /* Set the stack pointer. */ mov sp, x2 + /* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */ + mov x18, #0 + /* Invoke the entrypoint. */ blr x1 @@ -388,14 +413,6 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv: /* The stack isn't set up, so we'll need to trash a register. */ mov x22, x30 - /* Flush the entire data cache and invalidate the entire TLB. */ - bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv - - /* Invalidate the instruction cache, and ensure instruction consistency. */ - ic ialluis - dsb sy - isb - /* Set SCTLR_EL1 to disable the caches and mmu. */ /* SCTLR_EL1: */ /* - M = 0 */ @@ -413,27 +430,44 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv: mov x30, x22 ret -/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */ -.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits -.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv -.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function -_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv: +/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */ +.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits +.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv +.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function +_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv: /* The stack isn't set up, so we'll need to trash a register. */ - mov x23, x30 + mov x24, x30 - /* Ensure that the cache is coherent. */ - bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv + /* CacheLineIdAccessor clidr_el1; */ + mrs x10, clidr_el1 + /* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */ + ubfx x9, x10, #0x15, 3 + /* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */ + ubfx x10, x10, #0x18, 3 - bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv + /* int level = levels_of_unification */ - bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv + /* while (level <= levels_of_coherency) { */ + cmp w9, w10 + b.hi 1f - /* Invalidate the entire TLB, and ensure instruction consistency. */ - tlbi vmalle1is +0: + /* FlushEntireDataCacheImplWithoutStack(level); */ + mov w0, w9 + bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv + + /* level++; */ + cmp w9, w10 + add w9, w9, #1 + + /* } */ + b.cc 0b + + /* cpu::DataSynchronizationBarrier(); */ dsb sy - isb - mov x30, x23 +1: + mov x30, x24 ret /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheLocalWithoutStack() */ @@ -475,44 +509,27 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv: mov x30, x24 ret -/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */ -.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits -.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv -.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function -_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv: +/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */ +.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits +.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv +.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function +_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv: /* The stack isn't set up, so we'll need to trash a register. */ - mov x24, x30 + mov x23, x30 - /* CacheLineIdAccessor clidr_el1; */ - mrs x10, clidr_el1 - /* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */ - ubfx x9, x10, #0x15, 3 - /* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */ - ubfx x10, x10, #0x18, 3 + /* Ensure that the cache is coherent. */ + bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv - /* int level = levels_of_unification */ + bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv - /* while (level <= levels_of_coherency) { */ - cmp w9, w10 - b.hi 1f + bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv -0: - /* FlushEntireDataCacheImplWithoutStack(level); */ - mov w0, w9 - bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv - - /* level++; */ - cmp w9, w10 - add w9, w9, #1 - - /* } */ - b.cc 0b - - /* cpu::DataSynchronizationBarrier(); */ + /* Invalidate the entire TLB, and ensure instruction consistency. */ + tlbi vmalle1is dsb sy + isb -1: - mov x30, x24 + mov x30, x23 ret /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheImplWithoutStack() */ diff --git a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s index d81eb7e89..5a6b3e7ca 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -354,21 +354,12 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: mrs x17, ttbr0_el1 and x17, x17, #(0xFFFF << 48) - /* Check if FAR is valid by examining the FnV bit. */ - tbnz x16, #10, 8f - - /* FAR is valid, so we can invalidate the address it holds. */ + /* Invalidate the address held by FAR (and assume it is valid). */ mrs x16, far_el1 lsr x16, x16, #12 orr x17, x16, x17 tlbi vae1, x17 - b 9f -8: /* There's a TLB conflict and FAR isn't valid. */ - /* Invalidate the entire TLB. */ - tlbi aside1, x17 - -9: /* Return from a TLB conflict. */ /* Ensure instruction consistency. */ dsb ish isb @@ -444,6 +435,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: ERET_WITH_SPECULATION_BARRIER 2: /* The exception wasn't an triggered by copying memory from userspace. */ + /* NOTE: The following is, as of 19.0.0, now ifdef'd out on NX non-debug kernel. */ ldr x0, [sp, #8] ldr x1, [sp, #16] @@ -484,33 +476,16 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: b 3b 4: /* Check if there's a TLB conflict that caused the abort. */ - /* NOTE: There is a Nintendo bug in this code that we correct. */ - /* Nintendo compares the low 6 bits of x0 without restoring the value. */ - /* They intend to check the DFSC/IFSC bits of esr_el1, but because they */ - /* shifted esr earlier, the check is invalid and always fails. */ mrs x0, esr_el1 and x0, x0, #0x3F cmp x0, #0x30 b.ne 1b - /* Check if FAR is valid by examining the FnV bit. */ - /* NOTE: Nintendo again has a bug here, the same as above. */ - /* They do not refresh the value of x0, and again compare with */ - /* the relevant bit already masked out of x0. */ - mrs x0, esr_el1 - tbnz x0, #10, 5f - - /* FAR is valid, so we can invalidate the address it holds. */ + /* Invalidate the address held by FAR (and assume it is valid). */ mrs x0, far_el1 lsr x0, x0, #12 tlbi vaae1, x0 - b 6f -5: /* There's a TLB conflict and FAR isn't valid. */ - /* Invalidate the entire TLB. */ - tlbi vmalle1 - -6: /* Return from a TLB conflict. */ /* Ensure instruction consistency. */ dsb ish isb diff --git a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s index 362adc712..4b4b1bd3a 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s @@ -76,6 +76,9 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* v */ /* | u64 argument | u64 entrypoint | KThread::StackParameters (size 0x30) | */ + /* Clear the link register. */ + mov x30, #0 + /* Load the argument and entrypoint. */ ldp x0, x1, [sp], #0x10 @@ -84,4 +87,6 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* Mask I bit in DAIF */ msr daifclr, #2 - br x1 + + /* Invoke the function (by calling ams::kern::arch::arm64::InvokeSupervisorModeThread(argument, entrypoint)). */ + b _ZN3ams4kern4arch5arm6426InvokeSupervisorModeThreadEmm diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp index 6adff0754..d01ddd151 100644 --- a/mesosphere/kernel/source/kern_kernel_instantiations.cpp +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -111,4 +111,8 @@ namespace ams::kern { KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads.m_arr[core_id]; } KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads.m_arr[core_id]; } + __attribute__((constructor)) void ConfigureKTargetSystem() { + KSystemControl::ConfigureKTargetSystem(); + } + } diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 33fe56393..43979905c 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -49,7 +49,7 @@ namespace ams::kern::init::loader { constinit void *g_final_state[2]; - void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout) { + void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout, const uintptr_t &ini_base_address) { /* Adjust layout to be correct. */ { const ptrdiff_t layout_offset = reinterpret_cast(layout) - base_address; @@ -74,6 +74,12 @@ namespace ams::kern::init::loader { const uintptr_t diff = GetInteger(correct_base) - base_address; const size_t size = layout->rw_end_offset; + /* Check that the new kernel doesn't overlap with us. */ + MESOSPHERE_INIT_ABORT_UNLESS((GetInteger(correct_base) >= reinterpret_cast(__bin_end__)) || (GetInteger(correct_base) + size <= reinterpret_cast(__bin_start__))); + + /* Check that the new kernel doesn't overlap with the initial process binary. */ + MESOSPHERE_INIT_ABORT_UNLESS((ini_base_address + InitialProcessBinarySizeMax <= GetInteger(correct_base)) || (GetInteger(correct_base) + size <= ini_base_address)); + /* Conversion from KPhysicalAddress to void * is safe here, because MMU is not set up yet. */ std::memmove(reinterpret_cast(GetInteger(correct_base)), reinterpret_cast(base_address), size); base_address += diff; @@ -90,11 +96,11 @@ namespace ams::kern::init::loader { constexpr PageTableEntry KernelLdrRWXIdentityAttribute(PageTableEntry::Permission_KernelRWX, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); const uintptr_t kernel_ldr_base = util::AlignDown(reinterpret_cast(__bin_start__), PageSize); const uintptr_t kernel_ldr_size = util::AlignUp(reinterpret_cast(__bin_end__), PageSize) - kernel_ldr_base; - init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelRWXIdentityAttribute, allocator, 0); + init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelLdrRWXIdentityAttribute, allocator, 0); /* Map in the page table region as RW- for ourselves. */ constexpr PageTableEntry PageTableRegionRWAttribute(PageTableEntry::Permission_KernelRW, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); - init_pt.Map(page_table_region, page_table_region_size, page_table_region, KernelRWXIdentityAttribute, allocator, 0); + init_pt.Map(page_table_region, page_table_region_size, page_table_region, PageTableRegionRWAttribute, allocator, 0); /* Place the L1 table addresses in the relevant system registers. */ cpu::SetTtbr0El1(init_pt.GetTtbr0L1TableAddress()); @@ -165,7 +171,7 @@ namespace ams::kern::init::loader { uintptr_t Main(uintptr_t base_address, KernelLayout *layout, uintptr_t ini_base_address) { /* Relocate the kernel to the correct physical base address. */ /* Base address and layout are passed by reference and modified. */ - RelocateKernelPhysically(base_address, layout); + RelocateKernelPhysically(base_address, layout, ini_base_address); /* Validate kernel layout. */ const uintptr_t rx_offset = layout->rx_offset; @@ -229,6 +235,9 @@ namespace ams::kern::init::loader { /* Setup initial identity mapping. TTBR1 table passed by reference. */ SetupInitialIdentityMapping(init_pt, base_address, bss_end_offset, resource_end_address, InitialPageTableRegionSizeMax, g_initial_page_allocator, reinterpret_cast(base_address + sysreg_offset)); + /* NOTE: On 19.0.0+, Nintendo calls an unknown function here on init_pt and g_initial_page_allocator. */ + /* This is stubbed in prod KernelLdr. */ + /* Generate a random slide for the kernel's base address. */ const KVirtualAddress virtual_base_address = GetRandomKernelBaseAddress(init_pt, base_address, bss_end_offset); diff --git a/stratosphere/ams_mitm/source/amsmitm_main.cpp b/stratosphere/ams_mitm/source/amsmitm_main.cpp index 97e735f6e..9e0538135 100644 --- a/stratosphere/ams_mitm/source/amsmitm_main.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_main.cpp @@ -24,7 +24,7 @@ namespace ams { namespace { /* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */ - constexpr size_t MallocBufferSize = 32_MB; + constexpr size_t MallocBufferSize = 12_MB; alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize]; } diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp index cc37de024..ea6f1eb09 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -65,8 +65,8 @@ namespace ams::mitm::socket::resolver { } constexpr const char DefaultHostsFile[] = - "# All Nintendo servers\n" - "127.0.0.1 *nintendo*\n"; + "# Nintendo telemetry servers\n" + "127.0.0.1 receive-%.dg.srv.nintendo.net receive-%.er.srv.nintendo.net\n"; constinit os::SdkMutex g_redirection_lock; std::vector> g_redirection_list; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp index 62fd74ef3..025fcaba3 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp @@ -17,6 +17,7 @@ #include "../amsmitm_fs_utils.hpp" #include "fsmitm_romfs.hpp" #include "fsmitm_layered_romfs_storage.hpp" +#include "memlet/memlet.h" namespace ams::mitm::fs { @@ -26,6 +27,8 @@ namespace ams::mitm::fs { namespace { + constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB; + struct ApplicationWithDynamicHeapInfo { ncm::ProgramId program_id; size_t dynamic_app_heap_size; @@ -41,7 +44,7 @@ namespace ams::mitm::fs { /* Fire Emblem: Engage. */ /* Requirement ~32+ MB. */ /* No particular heap sensitivity. */ - { 0x0100A6301214E000, 16_MB, 0_MB }, + { 0x0100A6301214E000, 20_MB, 0_MB }, /* The Legend of Zelda: Tears of the Kingdom. */ /* Requirement ~48 MB. */ @@ -85,10 +88,12 @@ namespace ams::mitm::fs { /* NOTE: Lock not necessary, because this is the only location which do 0 -> non-zero. */ R_ABORT_UNLESS(MapImpl(std::addressof(this->heap_address), this->heap_size)); - AMS_ABORT_UNLESS(this->heap_address != 0); + AMS_ABORT_UNLESS(this->heap_address != 0 || this->heap_size == 0); /* Create heap. */ - util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); + if (this->heap_size > 0) { + util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); + } } } @@ -156,6 +161,52 @@ namespace ams::mitm::fs { R_RETURN(os::SetMemoryHeapSize(0)); } + constinit os::SharedMemoryType g_applet_shared_memory; + + Result MapAppletMemory(uintptr_t *out, size_t &size) { + /* Ensure that we can try to get a native handle for the shared memory. */ + AMS_FUNCTION_LOCAL_STATIC_CONSTINIT(bool, s_initialized_memlet, false); + if (AMS_UNLIKELY(!s_initialized_memlet)) { + R_ABORT_UNLESS(::memletInitialize()); + s_initialized_memlet = true; + } + + /* Try to get a shared handle for the memory. */ + ::Handle shmem_handle = INVALID_HANDLE; + u64 shmem_size = 0; + if (R_FAILED(::memletCreateAppletSharedMemory(std::addressof(shmem_handle), std::addressof(shmem_size), size))) { + /* If we fail, set the heap size to 0. */ + size = 0; + R_SUCCEED(); + } + + /* Set the output size. */ + size = shmem_size; + + /* Setup the shared memory. */ + os::AttachSharedMemory(std::addressof(g_applet_shared_memory), shmem_size, shmem_handle, true); + + /* Map the shared memory. */ + void *mem = os::MapSharedMemory(std::addressof(g_applet_shared_memory), os::MemoryPermission_ReadWrite); + AMS_ABORT_UNLESS(mem != nullptr); + + /* Set the output. */ + *out = reinterpret_cast(mem); + R_SUCCEED(); + } + + Result UnmapAppletMemory(uintptr_t, size_t) { + /* Check that it's possible for us to unmap. */ + AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) != os::InvalidNativeHandle); + + /* Unmap. */ + os::DestroySharedMemory(std::addressof(g_applet_shared_memory)); + + /* Check that we unmapped successfully. */ + AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) == os::InvalidNativeHandle); + R_SUCCEED(); + } + /* Dynamic allocation globals. */ constinit os::SdkMutex g_romfs_build_lock; constinit ncm::ProgramId g_dynamic_heap_program_id{}; @@ -164,6 +215,7 @@ namespace ams::mitm::fs { constinit DynamicHeap g_dynamic_app_heap; constinit DynamicHeap g_dynamic_sys_heap; + constinit DynamicHeap g_dynamic_let_heap; void InitializeDynamicHeapForBuildRomfs(ncm::ProgramId program_id) { if (program_id == g_dynamic_heap_program_id && g_dynamic_app_heap.heap_size > 0) { @@ -175,6 +227,10 @@ namespace ams::mitm::fs { if (g_dynamic_sys_heap.heap_size > 0) { g_dynamic_sys_heap.Map(); } + + if (g_dynamic_let_heap.heap_size > 0) { + g_dynamic_let_heap.Map(); + } } } @@ -183,15 +239,33 @@ namespace ams::mitm::fs { g_building_from_dynamic_heap = false; g_dynamic_app_heap.TryRelease(); + g_dynamic_let_heap.Reset(); + } + + constexpr bool CanAllocateFromDynamicAppletHeap(AllocationType type) { + switch (type) { + case AllocationType_FullPath: + case AllocationType_SourceInfo: + case AllocationType_Memory: + case AllocationType_TableCache: + return false; + default: + return true; + } } } void *AllocateTracked(AllocationType type, size_t size) { - AMS_UNUSED(type); - if (g_building_from_dynamic_heap) { - void *ret = g_dynamic_app_heap.Allocate(size); + void *ret = nullptr; + if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) { + ret = g_dynamic_let_heap.Allocate(size); + } + + if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) { + ret = g_dynamic_app_heap.Allocate(size); + } if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) { ret = g_dynamic_sys_heap.Allocate(size); @@ -211,7 +285,11 @@ namespace ams::mitm::fs { AMS_UNUSED(type); AMS_UNUSED(size); - if (g_dynamic_app_heap.TryFree(p)) { + if (g_dynamic_let_heap.TryFree(p)) { + if (!g_building_from_dynamic_heap) { + g_dynamic_let_heap.TryRelease(); + } + } else if (g_dynamic_app_heap.TryFree(p)) { if (!g_building_from_dynamic_heap) { g_dynamic_app_heap.TryRelease(); } @@ -1021,6 +1099,7 @@ namespace ams::mitm::fs { g_dynamic_heap_program_id = program_id; g_dynamic_app_heap.heap_size = GetDynamicAppHeapSize(g_dynamic_heap_program_id); g_dynamic_sys_heap.heap_size = GetDynamicSysHeapSize(g_dynamic_heap_program_id); + g_dynamic_let_heap.heap_size = MaximumRomfsBuildAppletMemorySize; /* Set output. */ *out_size = g_dynamic_app_heap.heap_size; diff --git a/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c new file mode 100644 index 000000000..ad14ebb2a --- /dev/null +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 . + */ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" +#include "memlet.h" + +static Service g_memletSrv; + +NX_GENERATE_SERVICE_GUARD(memlet); + +Result _memletInitialize(void) { + return smGetService(&g_memletSrv, "memlet"); +} + +void _memletCleanup(void) { + serviceClose(&g_memletSrv); +} + +Service* memletGetServiceSession(void) { + return &g_memletSrv; +} + +Result memletCreateAppletSharedMemory(Handle *out_shmem_h, u64 *out_size, u64 desired_size) { + return serviceDispatchInOut(&g_memletSrv, 65000, desired_size, *out_size, + .out_handle_attrs = { SfOutHandleAttr_HipcMove }, + .out_handles = out_shmem_h, + ); +} diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h similarity index 70% rename from libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp rename to stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h index 884cd0945..218761936 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h @@ -15,13 +15,18 @@ */ #pragma once -#include +#include -namespace ams::ldr { +#ifdef __cplusplus +extern "C" { +#endif - /* TODO: Is this really a FS type? What namespace does this actually live inside? */ - enum PlatformId { - PlatformId_Nx = 0, - }; +Result memletInitialize(void); +void memletExit(void); +Service* memletGetServiceSession(void); +Result memletCreateAppletSharedMemory(Handle *out_shmem_h, u64 *out_size, u64 desired_size); + +#ifdef __cplusplus } +#endif diff --git a/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h b/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h new file mode 100644 index 000000000..d7ce9a7a9 --- /dev/null +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h @@ -0,0 +1,65 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +typedef struct ServiceGuard { + Mutex mutex; + u32 refCount; +} ServiceGuard; + +NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g) +{ + mutexLock(&g->mutex); + return (g->refCount++) == 0; +} + +NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void)) +{ + if (R_FAILED(rc)) { + cleanupFunc(); + --g->refCount; + } + mutexUnlock(&g->mutex); + return rc; +} + +NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void)) +{ + mutexLock(&g->mutex); + if (g->refCount && (--g->refCount) == 0) + cleanupFunc(); + mutexUnlock(&g->mutex); +} + +#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \ +\ +static ServiceGuard g_##name##Guard; \ +NX_INLINE Result _##name##Initialize _paramdecl; \ +static void _##name##Cleanup(void); \ +\ +Result name##Initialize _paramdecl \ +{ \ + Result rc = 0; \ + if (serviceGuardBeginInit(&g_##name##Guard)) \ + rc = _##name##Initialize _parampass; \ + return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \ +} \ +\ +void name##Exit(void) \ +{ \ + serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \ +} + +#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ()) + +#ifdef __cplusplus +} +#endif diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c index 4b6d1b8cd..569ac2f61 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c @@ -48,6 +48,29 @@ static Result _nsGetApplicationContentPath(Service *s, void* out, size_t out_siz ); } +static Result _nsGetApplicationContentPath2(Service *s, void* out_path, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type) { + const struct { + u8 content_type; + u64 app_id; + } in = { content_type, app_id }; + + struct { + u8 attr; + u64 program_id; + } out; + + Result rc = serviceDispatchInOut(s, 2524, in, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { out_path, out_size } }, + ); + if (R_SUCCEEDED(rc)) { + *out_program_id = out.program_id; + *out_attr = out.attr; + } + + return rc; +} + static Result _nsResolveApplicationContentPath(Service* s, u64 app_id, NcmContentType content_type) { const struct { u8 content_type; @@ -93,6 +116,10 @@ Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_pr return _nsGetRunningApplicationProgramId(&doc->s, out_program_id, app_id); } +Result nswebGetApplicationContentPath2(NsDocumentInterface* doc, void* out, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type) { + return _nsGetApplicationContentPath2(&doc->s, out, out_size, out_program_id, out_attr, app_id, content_type); +} + void nsDocumentInterfaceClose(NsDocumentInterface* doc) { serviceClose(&doc->s); } diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h index afb8125d3..9cfd2774d 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h @@ -25,6 +25,7 @@ Result nsamGetRunningApplicationProgramIdFwd(Service* s, u64* out_program_id, u6 Result nswebGetApplicationContentPath(NsDocumentInterface* doc, void* out, size_t out_size, u8 *out_attr, u64 app_id, NcmContentType content_type); Result nswebResolveApplicationContentPath(NsDocumentInterface* doc, u64 app_id, NcmContentType content_type); Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_program_id, u64 app_id); +Result nswebGetApplicationContentPath2(NsDocumentInterface* doc, void* out, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type); void nsDocumentInterfaceClose(NsDocumentInterface* doc); diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp index 9568f9108..5613d267e 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp @@ -38,6 +38,11 @@ namespace ams::mitm::ns { R_RETURN(nswebGetRunningApplicationProgramId(m_srv.get(), reinterpret_cast(out.GetPointer()), static_cast(application_id))); } + Result NsDocumentService::GetApplicationContentPath2(const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type) { + static_assert(sizeof(*out_attr.GetPointer()) == sizeof(u8)); + R_RETURN(nswebGetApplicationContentPath2(m_srv.get(), out_path.GetPointer(), out_path.GetSize(), reinterpret_cast(out_program_id.GetPointer()), reinterpret_cast(out_attr.GetPointer()), static_cast(application_id), static_cast(content_type))); + } + Result NsWebMitmService::GetDocumentInterface(sf::Out> out) { /* Open a document interface. */ NsDocumentInterface doc; diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp index b08669e59..e9adbe46d 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp @@ -18,10 +18,11 @@ #include "ns_shim.h" -#define AMS_NS_DOCUMENT_MITM_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_attr, application_id, content_type)) \ - AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type), (application_id, content_type)) \ - AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out out, ncm::ProgramId application_id), (out, application_id), hos::Version_6_0_0) +#define AMS_NS_DOCUMENT_MITM_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_attr, application_id, content_type)) \ + AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type), (application_id, content_type)) \ + AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out out, ncm::ProgramId application_id), (out, application_id), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 2524, Result, GetApplicationContentPath2, (const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_program_id, out_attr, application_id, content_type), hos::Version_19_0_0) AMS_SF_DEFINE_INTERFACE(ams::mitm::ns::impl, IDocumentInterface, AMS_NS_DOCUMENT_MITM_INTERFACE_INFO, 0x0F9B1C00) @@ -47,6 +48,7 @@ namespace ams::mitm::ns { Result GetApplicationContentPath(const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type); Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type); Result GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id); + Result GetApplicationContentPath2(const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type); }; static_assert(impl::IsIDocumentInterface); diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp index f54bfbdbd..e0ceb6a19 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp @@ -67,7 +67,7 @@ namespace ams::mitm::settings { /* No truncation occurs assuming two-digits for all version number components. */ char display_version[sizeof(g_ams_firmware_version.display_version)]; - util::SNPrintf(display_version, sizeof(display_version), "%s|AMS_Sig %u.%u.%u|%c", g_ams_firmware_version.display_version, api_info.GetMajorVersion(), api_info.GetMinorVersion(), api_info.GetMicroVersion(), emummc_char); + util::SNPrintf(display_version, sizeof(display_version), "%s|AMS %u.%u.%u|%c", g_ams_firmware_version.display_version, api_info.GetMajorVersion(), api_info.GetMinorVersion(), api_info.GetMicroVersion(), emummc_char); std::memcpy(g_ams_firmware_version.display_version, display_version, sizeof(display_version)); } diff --git a/stratosphere/boot/source/boot_power_utils.cpp b/stratosphere/boot/source/boot_power_utils.cpp index 3f057e87c..0dc71b842 100644 --- a/stratosphere/boot/source/boot_power_utils.cpp +++ b/stratosphere/boot/source/boot_power_utils.cpp @@ -16,7 +16,6 @@ #include #include "boot_power_utils.hpp" #include "boot_pmic_driver.hpp" -#include "fusee_bin.h" namespace ams::boot { @@ -32,6 +31,10 @@ namespace ams::boot { /* Globals. */ alignas(os::MemoryPageSize) u8 g_work_page[os::MemoryPageSize]; + constexpr const u8 FuseeBin[] = { + #embed + }; + /* Helpers. */ void ClearIram() { /* Make page FFs. */ @@ -48,8 +51,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - for (size_t ofs = 0; ofs < fusee_bin_size; ofs += sizeof(g_work_page)) { - std::memcpy(g_work_page, fusee_bin + ofs, std::min(static_cast(fusee_bin_size - ofs), sizeof(g_work_page))); + for (size_t ofs = 0; ofs < sizeof(FuseeBin); ofs += sizeof(g_work_page)) { + std::memcpy(g_work_page, FuseeBin + ofs, std::min(static_cast(sizeof(FuseeBin) - ofs), sizeof(g_work_page))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -61,8 +64,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - for (size_t ofs = 0; ofs < fusee_bin_size; ofs += sizeof(g_work_page)) { - std::memcpy(g_work_page, fusee_bin + ofs, std::min(static_cast(fusee_bin_size - ofs), sizeof(g_work_page))); + for (size_t ofs = 0; ofs < sizeof(FuseeBin); ofs += sizeof(g_work_page)) { + std::memcpy(g_work_page, FuseeBin + ofs, std::min(static_cast(sizeof(FuseeBin) - ofs), sizeof(g_work_page))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -93,7 +96,7 @@ namespace ams::boot { } void SetInitialRebootPayload() { - ::ams::SetInitialRebootPayload(fusee_bin, fusee_bin_size); + ::ams::SetInitialRebootPayload(FuseeBin, sizeof(FuseeBin)); } void RebootForFatalError(ams::FatalErrorContext *ctx) { diff --git a/stratosphere/boot/system_module.mk b/stratosphere/boot/system_module.mk index be26006df..2f28eeee1 100644 --- a/stratosphere/boot/system_module.mk +++ b/stratosphere/boot/system_module.mk @@ -23,7 +23,7 @@ CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee.bin +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -67,15 +67,18 @@ endif .PHONY: clean all check_lib check_fusee #--------------------------------------------------------------------------------- -all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a +all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a $(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin @$(MAKE) __RECURSIVE__=1 OUTPUT=$(CURDIR)/$(ATMOSPHERE_OUT_DIR)/$(TARGET) \ DEPSDIR=$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) \ --no-print-directory -C $(ATMOSPHERE_BUILD_DIR) \ -f $(THIS_MAKEFILE) -$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib check_fusee +$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib @$(SILENTCMD)echo "Checked library." +$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin: check_fusee + @$(SILENTCMD)echo "Checked fusee." + ifeq ($(ATMOSPHERE_CHECKED_LIBSTRATOSPHERE),1) check_lib: else @@ -124,15 +127,7 @@ $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR @npdmtool $< $@ @echo built ... $(notdir $@) -boot_power_utils.o: fusee.bin.o - -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -fusee.bin.o: fusee.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) +boot_power_utils.o: CXXFLAGS += --embed-dir="$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/" -include $(DEPENDS) diff --git a/stratosphere/creport/creport.json b/stratosphere/creport/creport.json index cdd28371d..99859c3d2 100644 --- a/stratosphere/creport/creport.json +++ b/stratosphere/creport/creport.json @@ -110,6 +110,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } } diff --git a/stratosphere/dmnt.gen2/dmnt.gen2.json b/stratosphere/dmnt.gen2/dmnt.gen2.json index 918f1262c..e0d970789 100644 --- a/stratosphere/dmnt.gen2/dmnt.gen2.json +++ b/stratosphere/dmnt.gen2/dmnt.gen2.json @@ -105,6 +105,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } }] diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index e553efd0b..c1ecfb675 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -108,6 +108,8 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Bit Width: %x\n", opcode->begin_cond.bit_width); this->LogToDebugFile("Mem Type: %x\n", opcode->begin_cond.mem_type); this->LogToDebugFile("Cond Type: %x\n", opcode->begin_cond.cond_type); + this->LogToDebugFile("Inc Ofs reg: %d\n", opcode->begin_cond.include_ofs_reg); + this->LogToDebugFile("Ofs Reg Idx: %x\n", opcode->begin_cond.ofs_reg_index); this->LogToDebugFile("Rel Addr: %lx\n", opcode->begin_cond.rel_address); this->LogToDebugFile("Value: %lx\n", opcode->begin_cond.value.bit64); break; @@ -158,6 +160,11 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Opcode: Begin Keypress Conditional\n"); this->LogToDebugFile("Key Mask: %x\n", opcode->begin_keypress_cond.key_mask); break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + this->LogToDebugFile("Opcode: Begin Extended Keypress Conditional\n"); + this->LogToDebugFile("Key Mask: %x\n", opcode->begin_ext_keypress_cond.key_mask); + this->LogToDebugFile("Auto Repeat: %d\n", opcode->begin_ext_keypress_cond.auto_repeat); + break; case CheatVmOpcodeType_PerformArithmeticRegister: this->LogToDebugFile("Opcode: Perform Register Arithmetic\n"); this->LogToDebugFile("Bit Width: %x\n", opcode->perform_math_reg.bit_width); @@ -358,6 +365,7 @@ namespace ams::dmnt::cheat::impl { switch (opcode.opcode) { case CheatVmOpcodeType_BeginConditionalBlock: case CheatVmOpcodeType_BeginKeypressConditionalBlock: + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: case CheatVmOpcodeType_BeginRegisterConditionalBlock: opcode.begin_conditional_block = true; break; @@ -387,6 +395,8 @@ namespace ams::dmnt::cheat::impl { opcode.begin_cond.bit_width = (first_dword >> 24) & 0xF; opcode.begin_cond.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF); opcode.begin_cond.cond_type = (ConditionalComparisonType)((first_dword >> 16) & 0xF); + opcode.begin_cond.include_ofs_reg = ((first_dword >> 12) & 0xF) != 0; + opcode.begin_cond.ofs_reg_index = ((first_dword >> 8) & 0xF); opcode.begin_cond.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); opcode.begin_cond.value = GetNextVmInt(opcode.begin_cond.bit_width); } @@ -427,7 +437,8 @@ namespace ams::dmnt::cheat::impl { opcode.ldr_memory.bit_width = (first_dword >> 24) & 0xF; opcode.ldr_memory.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF); opcode.ldr_memory.reg_index = ((first_dword >> 16) & 0xF); - opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0; + opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF); + opcode.ldr_memory.offset_register = ((first_dword >> 8) & 0xF); opcode.ldr_memory.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); } break; @@ -460,6 +471,14 @@ namespace ams::dmnt::cheat::impl { opcode.begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; } break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + { + /* C4r00000 kkkkkkkk kkkkkkkk */ + /* Read additional words. */ + opcode.begin_ext_keypress_cond.key_mask = (u64)GetNextDword() << 32ul | (u64)GetNextDword(); + opcode.begin_ext_keypress_cond.auto_repeat = ((first_dword >> 20) & 0xF) != 0; + } + break; case CheatVmOpcodeType_PerformArithmeticRegister: { /* 9TCRSIs0 (VVVVVVVV (VVVVVVVV)) */ @@ -734,6 +753,8 @@ namespace ams::dmnt::cheat::impl { return metadata->alias_extents.base + rel_address; case MemoryAccessType_Aslr: return metadata->aslr_extents.base + rel_address; + case MemoryAccessType_NonRelative: + return rel_address; } } @@ -769,6 +790,7 @@ namespace ams::dmnt::cheat::impl { return true; } + static u64 s_keyold = 0; void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) { CheatVmOpcode cur_opcode; u64 kHeld = 0; @@ -824,7 +846,7 @@ namespace ams::dmnt::cheat::impl { case CheatVmOpcodeType_BeginConditionalBlock: { /* Read value from memory. */ - u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, cur_opcode.begin_cond.rel_address); + u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, (cur_opcode.begin_cond.include_ofs_reg) ? m_registers[cur_opcode.begin_cond.ofs_reg_index] + cur_opcode.begin_cond.rel_address : cur_opcode.begin_cond.rel_address); u64 src_value = 0; switch (cur_opcode.store_static.bit_width) { case 1: @@ -896,8 +918,12 @@ namespace ams::dmnt::cheat::impl { { /* Choose source address. */ u64 src_address; - if (cur_opcode.ldr_memory.load_from_reg) { + if (cur_opcode.ldr_memory.load_from_reg == 1) { src_address = m_registers[cur_opcode.ldr_memory.reg_index] + cur_opcode.ldr_memory.rel_address; + } else if (cur_opcode.ldr_memory.load_from_reg == 2) { + src_address = m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address; + } else if (cur_opcode.ldr_memory.load_from_reg == 3) { + src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address); } else { src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, cur_opcode.ldr_memory.rel_address); } @@ -982,6 +1008,18 @@ namespace ams::dmnt::cheat::impl { this->SkipConditionalBlock(true); } break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + /* Check for keypress. */ + if (!cur_opcode.begin_ext_keypress_cond.auto_repeat) { + if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & s_keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) { + /* Keys not pressed. Skip conditional block. */ + this->SkipConditionalBlock(true); + } + } else if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != cur_opcode.begin_ext_keypress_cond.key_mask) { + /* Keys not pressed. Skip conditional block. */ + this->SkipConditionalBlock(true); + } + break; case CheatVmOpcodeType_PerformArithmeticRegister: { const u64 operand_1_value = m_registers[cur_opcode.perform_math_reg.src_reg_1_index]; @@ -1022,6 +1060,34 @@ namespace ams::dmnt::cheat::impl { case RegisterArithmeticType_None: res_val = operand_1_value; break; + case RegisterArithmeticType_FloatAddition: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) + std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) + std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatSubtraction: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) - std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) - std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatMultiplication: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) * std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) * std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatDivision: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) / std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) / std::bit_cast(operand_2_value)); + } + break; } @@ -1304,6 +1370,7 @@ namespace ams::dmnt::cheat::impl { break; } } + s_keyold = kHeld; } } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp index 0eb47b2a2..2dd958d5c 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -43,6 +43,7 @@ namespace ams::dmnt::cheat::impl { CheatVmOpcodeType_SaveRestoreRegister = 0xC1, CheatVmOpcodeType_SaveRestoreRegisterMask = 0xC2, CheatVmOpcodeType_ReadWriteStaticRegister = 0xC3, + CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock = 0xC4, /* This is a meta entry, and not a real opcode. */ /* This is to facilitate multi-nybble instruction decoding. */ @@ -59,6 +60,7 @@ namespace ams::dmnt::cheat::impl { MemoryAccessType_Heap = 1, MemoryAccessType_Alias = 2, MemoryAccessType_Aslr = 3, + MemoryAccessType_NonRelative = 4, }; enum ConditionalComparisonType : u32 { @@ -84,6 +86,10 @@ namespace ams::dmnt::cheat::impl { RegisterArithmeticType_LogicalXor = 8, RegisterArithmeticType_None = 9, + RegisterArithmeticType_FloatAddition = 10, + RegisterArithmeticType_FloatSubtraction = 11, + RegisterArithmeticType_FloatMultiplication = 12, + RegisterArithmeticType_FloatDivision = 13, }; enum StoreRegisterOffsetType : u32 { @@ -138,6 +144,8 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; ConditionalComparisonType cond_type; + bool include_ofs_reg; + u32 ofs_reg_index; u64 rel_address; VmInt value; }; @@ -161,7 +169,8 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; u32 reg_index; - bool load_from_reg; + u8 load_from_reg; + u8 offset_register; u64 rel_address; }; @@ -185,6 +194,11 @@ namespace ams::dmnt::cheat::impl { u32 key_mask; }; + struct BeginExtendedKeypressConditionalOpcode { + u64 key_mask; + bool auto_repeat; + }; + struct PerformArithmeticRegisterOpcode { u32 bit_width; RegisterArithmeticType math_type; @@ -259,6 +273,7 @@ namespace ams::dmnt::cheat::impl { StoreStaticToAddressOpcode str_static; PerformArithmeticStaticOpcode perform_math_static; BeginKeypressConditionalOpcode begin_keypress_cond; + BeginExtendedKeypressConditionalOpcode begin_ext_keypress_cond; PerformArithmeticRegisterOpcode perform_math_reg; StoreRegisterToAddressOpcode str_register; BeginRegisterConditionalOpcode begin_reg_cond; diff --git a/stratosphere/fatal/fatal.json b/stratosphere/fatal/fatal.json index 45b718089..aef307a68 100644 --- a/stratosphere/fatal/fatal.json +++ b/stratosphere/fatal/fatal.json @@ -104,6 +104,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } }] diff --git a/stratosphere/loader/source/ldr_capabilities.cpp b/stratosphere/loader/source/ldr_capabilities.cpp index 6835267b3..b3bc25e65 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -308,10 +308,19 @@ namespace ams::ldr { ); DEFINE_CAPABILITY_CLASS(DebugFlags, - DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_CAPABILITY_FIELD(ForceDebug, AllowDebug, 1, bool); + DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_CAPABILITY_FIELD(ForceDebugProd, AllowDebug, 1, bool); + DEFINE_CAPABILITY_FIELD(ForceDebug, ForceDebugProd, 1, bool); bool IsValid(const util::BitPack32 *kac, size_t kac_count) const { + u32 total = 0; + if (this->GetAllowDebug()) { ++total; } + if (this->GetForceDebugProd()) { ++total; } + if (this->GetForceDebug()) { ++total; } + if (total > 1) { + return false; + } + for (size_t i = 0; i < kac_count; i++) { if (GetCapabilityId(kac[i]) == Id) { const auto restriction = Decode(kac[i]); @@ -319,12 +328,14 @@ namespace ams::ldr { return (restriction.GetValue() & this->GetValue()) == this->GetValue(); } } + return false; } - static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug) { + static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug_prod, bool force_debug) { util::BitPack32 encoded{IdBitsValue}; encoded.Set(allow_debug); + encoded.Set(force_debug_prod); encoded.Set(force_debug); return encoded; } @@ -406,7 +417,21 @@ namespace ams::ldr { kac[i] = CapabilityApplicationType::Encode(flags & ProgramInfoFlag_ApplicationTypeMask); break; case CapabilityId::DebugFlags: - kac[i] = CapabilityDebugFlags::Encode((flags & ProgramInfoFlag_AllowDebug) != 0, CapabilityDebugFlags::Decode(cap).GetForceDebug()); + kac[i] = CapabilityDebugFlags::Encode((flags & ProgramInfoFlag_AllowDebug) != 0, CapabilityDebugFlags::Decode(cap).GetForceDebugProd(), CapabilityDebugFlags::Decode(cap).GetForceDebug()); + break; + default: + break; + } + } + } + + void FixDebugCapabilityForHbl(util::BitPack32 *kac, size_t count) { + for (size_t i = 0; i < count; ++i) { + const auto cap = kac[i]; + switch (GetCapabilityId(cap)) { + case CapabilityId::DebugFlags: + /* 19.0.0+ disallows more than one flag set; we are always DebugMode for kernel, so ForceDebug is the most powerful/flexible flag to set. */ + kac[i] = CapabilityDebugFlags::Encode(false, false, true); break; default: break; diff --git a/stratosphere/loader/source/ldr_capabilities.hpp b/stratosphere/loader/source/ldr_capabilities.hpp index 0a91b23cc..21748a7fb 100644 --- a/stratosphere/loader/source/ldr_capabilities.hpp +++ b/stratosphere/loader/source/ldr_capabilities.hpp @@ -23,6 +23,8 @@ namespace ams::ldr { u16 MakeProgramInfoFlag(const util::BitPack32 *kac, size_t count); void UpdateProgramInfoFlag(u16 flags, util::BitPack32 *kac, size_t count); + void FixDebugCapabilityForHbl(util::BitPack32 *kac, size_t count); + void PreProcessCapability(util::BitPack32 *kac, size_t count); } diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index 2a704bcd5..f1d0dfa14 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -25,12 +25,12 @@ namespace ams::ldr { } /* ScopedCodeMount functionality. */ - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc, platform); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, attrs); } - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc, platform); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, attrs); } ScopedCodeMount::~ScopedCodeMount() { @@ -46,28 +46,28 @@ namespace ams::ldr { } } - Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, PlatformId platform) { + Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { /* Capture override status, if necessary. */ this->EnsureOverrideStatus(loc); AMS_ABORT_UNLESS(m_has_status); /* Get the content path. */ char content_path[fs::EntryNameLengthMax + 1]; - R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform)); + R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, attrs)); /* Get the content attributes. */ - const auto content_attributes = GetPlatformContentAttributes(platform); + const auto content_attributes = attrs.content_attributes; /* Mount the atmosphere code file system. */ - R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); + R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id), m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); m_mounted_ams = true; /* Mount the sd or base code file system. */ - R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id)); + R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id))); m_mounted_sd_or_code = true; /* Mount the base code file system. */ - if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id))) { + if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id)))) { m_mounted_code = true; } @@ -83,7 +83,7 @@ namespace ams::ldr { } /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform) { + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { /* Check for storage id none. */ if (static_cast(loc.storage_id) == ncm::StorageId::None) { std::memset(out_path, 0, out_size); @@ -92,7 +92,7 @@ namespace ams::ldr { } /* Get the content attributes. */ - const auto content_attributes = GetPlatformContentAttributes(platform); + const auto content_attributes = attrs.content_attributes; AMS_UNUSED(content_attributes); lr::Path path; @@ -166,12 +166,4 @@ namespace ams::ldr { R_SUCCEED(); } - fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform) { - switch (platform) { - case PlatformId_Nx: - return fs::ContentAttributes_None; - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } - } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index bc5848826..d20c80709 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -34,8 +34,8 @@ namespace ams::ldr { bool m_mounted_sd_or_code; bool m_mounted_code; public: - ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform); - ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, PlatformId platform); + ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); + ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs); ~ScopedCodeMount(); Result GetResult() const { @@ -59,7 +59,7 @@ namespace ams::ldr { return m_base_code_verification_data; } private: - Result Initialize(const ncm::ProgramLocation &loc, PlatformId platform); + Result Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); void EnsureOverrideStatus(const ncm::ProgramLocation &loc); }; @@ -76,10 +76,8 @@ namespace ams::ldr { #define ENCODE_CMPT_PATH(relative) "cmpt:" relative /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform); + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc); Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc); - fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform); - } diff --git a/stratosphere/loader/source/ldr_embedded_es_patches.inc b/stratosphere/loader/source/ldr_embedded_es_patches.inc deleted file mode 100644 index 0d9b02327..000000000 --- a/stratosphere/loader/source/ldr_embedded_es_patches.inc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 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 . - */ - -/* Patch fallback case to mov w0, #1 rather than retrieving settings flag. */ -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_1_0_0[] = { - { 0x4884, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_2_3_0[] = { - { 0x4758, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_3_0_0[] = { - { 0x4710, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_3_0_2[] = { - { 0x4710, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_4_0_0[] = { - { 0x553C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_5_0_0[] = { - { 0x5E94, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_5_1_0[] = { - { 0x5E94, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_6_0_0[] = { - { 0x4BCD4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_6_1_0[] = { - { 0x4BCD4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_7_0_0[] = { - { 0x4D5F4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_8_0_1[] = { - { 0x4EDC4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_8_1_0[] = { - { 0x4EDC4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_9_0_0[] = { - { 0x2D2D4, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_10_0_0[] = { - { 0x2DB98, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_10_1_0[] = { - { 0x2DBAC, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_11_0_0[] = { - { 0x2CFCC, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_12_0_0[] = { - { 0x2E47C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_12_1_0[] = { - { 0x2E51C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_13_0_0[] = { - { 0x31428, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_13_1_0[] = { - { 0x31928, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_14_0_0[] = { - { 0x662D8, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_15_0_0[] = { - { 0x649EC, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_16_0_0[] = { - { 0x64A6C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_17_0_0[] = { - { 0x6720C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_18_0_0[] = { - { 0x6964C, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry DisableTicketVerificationPatches_19_0_0[] = { - { 0x06A3F8, "\xE0\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatch DisableTicketVerificationPatches[] = { - { ParseModuleId("F7271147BA178C4E9F6451C62B10E668E6F8DECC"), util::size(DisableTicketVerificationPatches_1_0_0), DisableTicketVerificationPatches_1_0_0 }, /* 1.0.0 */ - { ParseModuleId("76935CA6235CA150D790D4DDF09CA3488AEF50D8"), util::size(DisableTicketVerificationPatches_2_3_0), DisableTicketVerificationPatches_2_3_0 }, /* 2.3.0 */ - { ParseModuleId("F92CFF283777465AFBCC6E160C10EFE7AADC4D3C"), util::size(DisableTicketVerificationPatches_3_0_0), DisableTicketVerificationPatches_3_0_0 }, /* 3.0.0 */ - { ParseModuleId("F86D615F9FC6F0D16C3458BE58C64594DBDAB0DF"), util::size(DisableTicketVerificationPatches_3_0_2), DisableTicketVerificationPatches_3_0_2 }, /* 3.0.2 */ - { ParseModuleId("7135C20E752183914606CCE81293F24B738C3AEF"), util::size(DisableTicketVerificationPatches_4_0_0), DisableTicketVerificationPatches_4_0_0 }, /* 4.0.0-4.1.0 */ - { ParseModuleId("A6E7D98BD335371E1B9A96F6241EA3E83B0C36F4"), util::size(DisableTicketVerificationPatches_5_0_0), DisableTicketVerificationPatches_5_0_0 }, /* 5.0.0-5.0.2 */ - { ParseModuleId("C0BFC6518707AC975295A0B656A051DA885A9045"), util::size(DisableTicketVerificationPatches_5_1_0), DisableTicketVerificationPatches_5_1_0 }, /* 5.1.0 */ - { ParseModuleId("CBF2D40A2210C4EE1137F80098DB776EAC7DDCC1"), util::size(DisableTicketVerificationPatches_6_0_0), DisableTicketVerificationPatches_6_0_0 }, /* 6.0.0-6.0.1 */ - { ParseModuleId("9C1B205852731D054B070529D320AD9649E7796C"), util::size(DisableTicketVerificationPatches_6_1_0), DisableTicketVerificationPatches_6_1_0 }, /* 6.1.0-6.2.0 */ - { ParseModuleId("D2D2430244D162C9FAABE8C89A58C6E3962160F1"), util::size(DisableTicketVerificationPatches_7_0_0), DisableTicketVerificationPatches_7_0_0 }, /* 7.0.0-7.0.1 */ - { ParseModuleId("39E7884F7DDEA9BE4FF9F7187898FACC466A080A"), util::size(DisableTicketVerificationPatches_8_0_1), DisableTicketVerificationPatches_8_0_1 }, /* 8.0.1 */ - { ParseModuleId("CF8FB4F82D3E2D56720E1EDB14AB06543343E042"), util::size(DisableTicketVerificationPatches_8_1_0), DisableTicketVerificationPatches_8_1_0 }, /* 8.1.0-8.1.1 */ - { ParseModuleId("34E95FF2929B5B767DCFD41D108AD927D2D7F5DC"), util::size(DisableTicketVerificationPatches_9_0_0), DisableTicketVerificationPatches_9_0_0 }, /* 9.0.0-9.2.0 */ - { ParseModuleId("03E4EB5556B98B327D1353E8AA2C7ADF2C544470"), util::size(DisableTicketVerificationPatches_10_0_0), DisableTicketVerificationPatches_10_0_0 }, /* 10.0.0-10.0.4 */ - { ParseModuleId("5AA09E1AF740A91D0F73ADFAE81A63E8AC0610D2"), util::size(DisableTicketVerificationPatches_10_1_0), DisableTicketVerificationPatches_10_1_0 }, /* 10.1.0-10.2.0 */ - { ParseModuleId("3B8BF56DBEC7225D2EE666B009C42C0DC4552010"), util::size(DisableTicketVerificationPatches_11_0_0), DisableTicketVerificationPatches_11_0_0 }, /* 11.0.0-11.0.1 */ - { ParseModuleId("F48ABC3EF41A0555800127D172C9B8D2C653243A"), util::size(DisableTicketVerificationPatches_12_0_0), DisableTicketVerificationPatches_12_0_0 }, /* 12.0.0-12.0.3 */ - { ParseModuleId("1114E9102F1EBCD1B0EAF19C927362CFCB8B5D2C"), util::size(DisableTicketVerificationPatches_12_1_0), DisableTicketVerificationPatches_12_1_0 }, /* 12.1.0 */ - { ParseModuleId("D0ECC9483E636AE19FE3E314DB41CB18019977D7"), util::size(DisableTicketVerificationPatches_13_0_0), DisableTicketVerificationPatches_13_0_0 }, /* 13.0.0 */ - { ParseModuleId("98BB737D9780E9FE3117981A77A09FF6756DBC2E"), util::size(DisableTicketVerificationPatches_13_1_0), DisableTicketVerificationPatches_13_1_0 }, /* 13.1.0-13.2.1 */ - { ParseModuleId("621351EB04199CF0B7A899896C451F2FD1B7A1CE"), util::size(DisableTicketVerificationPatches_14_0_0), DisableTicketVerificationPatches_14_0_0 }, /* 14.0.0-14.1.2 */ - { ParseModuleId("4FB9AFAED8A9093A3D88F6D61158B1C165F9444A"), util::size(DisableTicketVerificationPatches_15_0_0), DisableTicketVerificationPatches_15_0_0 }, /* 15.0.0-15.0.1 */ - { ParseModuleId("127904316C924326084288641825FE5DC259AF6B"), util::size(DisableTicketVerificationPatches_16_0_0), DisableTicketVerificationPatches_16_0_0 }, /* 16.0.0-16.1.0 */ - { ParseModuleId("02DCD930D0A7462451E9973AB2022D697C77614B"), util::size(DisableTicketVerificationPatches_17_0_0), DisableTicketVerificationPatches_17_0_0 }, /* 17.0.0-17.0.1 */ - { ParseModuleId("897C2CF2777B3A8845640C096933ACE61DD12272"), util::size(DisableTicketVerificationPatches_18_0_0), DisableTicketVerificationPatches_18_0_0 }, /* 18.0.0-18.1.0 */ - { ParseModuleId("4A258ADE9176A7F263532C2A4C30187A0B00C012"), util::size(DisableTicketVerificationPatches_19_0_0), DisableTicketVerificationPatches_19_0_0 }, /* 19.0.0 */ -}; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_embedded_nifm_patches.inc b/stratosphere/loader/source/ldr_embedded_nifm_patches.inc deleted file mode 100755 index 25f8fde75..000000000 --- a/stratosphere/loader/source/ldr_embedded_nifm_patches.inc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 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 . - */ - -/* Patch fallback case to mov w0, #1 rather than retrieving settings flag. */ -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_1_0_0[] = { - { 0x304C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_2_0_0[] = { - { 0x33C4, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_2_1_0[] = { - { 0x3300, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_3_0_0[] = { - { 0x36B4, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_3_0_1[] = { - { 0x36B4, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_4_0_0[] = { - { 0x3698, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_5_0_0[] = { - { 0x2075C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_5_1_0[] = { - { 0x207EC, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_6_0_0[] = { - { 0x74B2C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_6_1_0[] = { - { 0x74B6C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_7_0_0[] = { - { 0x76C4C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_8_0_0[] = { - { 0x7854C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_9_0_0[] = { - { 0xE1EC, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_9_1_0[] = { - { 0xE1EC, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_10_0_0[] = { - { 0xF67C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_11_0_0[] = { - { 0xF32C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_12_0_0[] = { - { 0x106C8, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_12_1_0[] = { - { 0x106C8, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_13_0_0[] = { - { 0x10740, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_13_1_0[] = { - { 0x10740, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_14_0_0[] = { - { 0x44238, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_15_0_0[] = { - { 0x79E60, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_16_0_0[] = { - { 0x7A80C, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_17_0_0[] = { - { 0x809E0, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_18_0_0[] = { - { 0x83560, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_18_0_1[] = { - { 0x83560, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatchEntry ForceCommunicationEnabledPatches_19_0_0[] = { - { 0x086520, "\x00\x30\x9A\xD2\x00\x1E\xA1\xF2\x61\x01\x00\xD4\xE0\x03\x1F\xAA\xC0\x03\x5F\xD6", 20 }, -}; - -constexpr inline const EmbeddedPatch ForceCommunicationEnabledPatches[] = { - { ParseModuleId("D47D1506009B340829CD545B2A3F3AA7881FBADA"), util::size(ForceCommunicationEnabledPatches_1_0_0), ForceCommunicationEnabledPatches_1_0_0 }, /* 1.0.0 */ - { ParseModuleId("E6BFDADD5C69E17D43B7C67E2B2EE8B2E50C8E1F"), util::size(ForceCommunicationEnabledPatches_2_0_0), ForceCommunicationEnabledPatches_2_0_0 }, /* 2.0.0 */ - { ParseModuleId("AD32FB6D8F36668C586E538E32576A8D6A3931C0"), util::size(ForceCommunicationEnabledPatches_2_1_0), ForceCommunicationEnabledPatches_2_1_0 }, /* 2.1.0-2.3.0 */ - { ParseModuleId("881206E6B5078EFC4E2C30D7B33E33AD266538C6"), util::size(ForceCommunicationEnabledPatches_3_0_0), ForceCommunicationEnabledPatches_3_0_0 }, /* 3.0.0 */ - { ParseModuleId("5835E2DADB4DD570DD811ABF521FA91AC3C7B717"), util::size(ForceCommunicationEnabledPatches_3_0_1), ForceCommunicationEnabledPatches_3_0_1 }, /* 3.0.1-3.0.2 */ - { ParseModuleId("38774C42DFCB8B9D7AA61550D6AF7D335472556C"), util::size(ForceCommunicationEnabledPatches_4_0_0), ForceCommunicationEnabledPatches_4_0_0 }, /* 4.0.0-4.1.0 */ - { ParseModuleId("B6966381A806655B718F1BF11DB5FF836E3085F7"), util::size(ForceCommunicationEnabledPatches_5_0_0), ForceCommunicationEnabledPatches_5_0_0 }, /* 5.0.0-5.0.2 */ - { ParseModuleId("D82361E0D66DC01AFA3B5116532E5E1ED569C578"), util::size(ForceCommunicationEnabledPatches_5_1_0), ForceCommunicationEnabledPatches_5_1_0 }, /* 5.1.0 */ - { ParseModuleId("3AED90979B380C6415F975F5B784BEA2B4730E8C"), util::size(ForceCommunicationEnabledPatches_6_0_0), ForceCommunicationEnabledPatches_6_0_0 }, /* 6.0.0-6.0.1 */ - { ParseModuleId("43F10952AE80CFADC39A0BF59EA4E552EF4A4528"), util::size(ForceCommunicationEnabledPatches_6_1_0), ForceCommunicationEnabledPatches_6_1_0 }, /* 6.1.0-6.2.0 */ - { ParseModuleId("929014BFCFE462FD76B2BB3454FB304F63C73AC2"), util::size(ForceCommunicationEnabledPatches_7_0_0), ForceCommunicationEnabledPatches_7_0_0 }, /* 7.0.0-7.0.1 */ - { ParseModuleId("FD53CB863709DFFEC19C0889F61D4C424AFFD4ED"), util::size(ForceCommunicationEnabledPatches_8_0_0), ForceCommunicationEnabledPatches_8_0_0 }, /* 8.0.0-8.1.0 */ - { ParseModuleId("7DF07326B6B50CA37F19C1C44F9458406C536B30"), util::size(ForceCommunicationEnabledPatches_9_0_0), ForceCommunicationEnabledPatches_9_0_0 }, /* 9.0.0-9.0.1 */ - { ParseModuleId("9C72C47F0310F7C9F487047D8EB42DBB96882088"), util::size(ForceCommunicationEnabledPatches_9_1_0), ForceCommunicationEnabledPatches_9_1_0 }, /* 9.1.0-9.2.0 */ - { ParseModuleId("5DA461C7B6CAE6B88EDF4F914F7CBCF0943B10BB"), util::size(ForceCommunicationEnabledPatches_10_0_0), ForceCommunicationEnabledPatches_10_0_0 }, /* 10.0.0-10.2.0 */ - { ParseModuleId("7A43F840337C28D453718843608EEFF78AFD460B"), util::size(ForceCommunicationEnabledPatches_11_0_0), ForceCommunicationEnabledPatches_11_0_0 }, /* 11.0.0-11.0.1 */ - { ParseModuleId("A85F50FBA10E06A3EBA3D3FACB9E075B218C7D6D"), util::size(ForceCommunicationEnabledPatches_12_0_0), ForceCommunicationEnabledPatches_12_0_0 }, /* 12.0.0-12.0.3 */ - { ParseModuleId("69E25CDEEED5C6520AC2AC8E5EAE01CD8FC46E40"), util::size(ForceCommunicationEnabledPatches_12_1_0), ForceCommunicationEnabledPatches_12_1_0 }, /* 12.1.0 */ - { ParseModuleId("8CB532EA199207191F04CE3DDECEC854C7CF07D6"), util::size(ForceCommunicationEnabledPatches_13_0_0), ForceCommunicationEnabledPatches_13_0_0 }, /* 13.0.0 */ - { ParseModuleId("6F02D68B1DCD2AFFBAED14B5933F81F3C327E537"), util::size(ForceCommunicationEnabledPatches_13_1_0), ForceCommunicationEnabledPatches_13_1_0 }, /* 13.1.0-13.2.1 */ - { ParseModuleId("BA91B5A61E423F51FB83B2C9E6C153CC5AE27DCB"), util::size(ForceCommunicationEnabledPatches_14_0_0), ForceCommunicationEnabledPatches_14_0_0 }, /* 14.0.0-14.1.2 */ - { ParseModuleId("A188828ADF447425D97901462EBF732D2E29BC4E"), util::size(ForceCommunicationEnabledPatches_15_0_0), ForceCommunicationEnabledPatches_15_0_0 }, /* 15.0.0-15.0.1 */ - { ParseModuleId("A2C3AEE4E5A954908BEBAEDEA2010095E9E521B2"), util::size(ForceCommunicationEnabledPatches_16_0_0), ForceCommunicationEnabledPatches_16_0_0 }, /* 16.0.0-16.1.0 */ - { ParseModuleId("440F71259BCA1E97EA3663CBD6EC9315951F9E96"), util::size(ForceCommunicationEnabledPatches_17_0_0), ForceCommunicationEnabledPatches_17_0_0 }, /* 17.0.0-17.0.1 */ - { ParseModuleId("184A3F5734F456D0718FA35D15D8410A9BDFC537"), util::size(ForceCommunicationEnabledPatches_18_0_0), ForceCommunicationEnabledPatches_18_0_0 }, /* 18.0.0 */ - { ParseModuleId("0C4C2220D90155B139E254179D2D35244B32C9C1"), util::size(ForceCommunicationEnabledPatches_18_0_1), ForceCommunicationEnabledPatches_18_0_1 }, /* 18.0.1-18.1.0 */ - { ParseModuleId("1BD31ABF1E3E607CA79B29CF7D7B10758FF93FA0"), util::size(ForceCommunicationEnabledPatches_19_0_0), ForceCommunicationEnabledPatches_19_0_0 }, /* 19.0.0 */ -}; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_embedded_nim_patches.inc b/stratosphere/loader/source/ldr_embedded_nim_patches.inc deleted file mode 100644 index ffe70714b..000000000 --- a/stratosphere/loader/source/ldr_embedded_nim_patches.inc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 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 . - */ - -/* Patch fallback case to mov w0, #1 rather than retrieving settings flag. */ -constexpr inline const EmbeddedPatchEntry AmsProdinfoBlankerFix_17_0_0[] = { - { 0x1334A8, "\xE2\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry AmsProdinfoBlankerFix_18_0_0[] = { - { 0x139F48, "\xE2\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatchEntry AmsProdinfoBlankerFix_19_0_0[] = { - { 0x1387A8, "\xE2\x03\x1F\xAA", 4 }, -}; - -constexpr inline const EmbeddedPatch AmsProdinfoBlankerFix[] = { - { ParseModuleId("C14BC0AD5027F6B6B49A5A6B2D52D5E8306EE1D2"), util::size(AmsProdinfoBlankerFix_17_0_0), AmsProdinfoBlankerFix_17_0_0 }, /* 17.0.0-17.0.1 */ - { ParseModuleId("DAEEEF46027BA6E83688C05C396E6C6B17F29001"), util::size(AmsProdinfoBlankerFix_18_0_0), AmsProdinfoBlankerFix_18_0_0 }, /* 18.0.0-18.1.0 */ - { ParseModuleId("C54A1B3EB06FF3F5DCCBAC1AEFD5CA5459A2A6E6"), util::size(AmsProdinfoBlankerFix_19_0_0), AmsProdinfoBlankerFix_19_0_0 }, /* 19.0.0 */ -}; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index 4ae97c2ec..f91f1da82 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -64,6 +64,16 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_18_0_0[] = { { 0x6E48, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_19_0_0[] = { + { 0x6D90, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x6E10, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_20_0_0[] = { + { 0x7010, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x7090, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -76,4 +86,6 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("225865A442B4B66E8BD14B3E9450B901BDF29A40"), util::size(Usb30ForceEnablePatches_16_0_0), Usb30ForceEnablePatches_16_0_0 }, /* 16.0.0 */ { ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */ { ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */ + { ParseModuleId("54BB9BB32C958E02752DC5E4AE8D016BFE1F5418"), util::size(Usb30ForceEnablePatches_19_0_0), Usb30ForceEnablePatches_19_0_0 }, /* 19.0.0 */ + { ParseModuleId("40E80E7442C0DFC985315E6F9E8C77229818AC0F"), util::size(Usb30ForceEnablePatches_20_0_0), Usb30ForceEnablePatches_20_0_0 }, /* 20.0.0 */ }; diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 8a888caac..17a4a9160 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -27,72 +27,72 @@ namespace ams::ldr { constinit ArgumentStore g_argument_store; - bool IsValidPlatform(PlatformId platform) { - return platform == PlatformId_Nx; - } - - Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { - /* Check that the platform is valid. */ - R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); - - /* Get the location and override status. */ - ncm::ProgramLocation loc; - cfg::OverrideStatus override_status; - R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); - path[sizeof(path) - 1] = '\x00'; - - /* Create the process. */ - R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform)); - } - - Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, PlatformId platform) { - /* Check that the platform is valid. */ - R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); - - /* Zero output. */ - std::memset(out, 0, sizeof(*out)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); - path[sizeof(path) - 1] = '\x00'; - - /* Get the program info. */ - cfg::OverrideStatus status; - R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, platform)); - - if (loc.program_id != out->program_id) { - /* Redirect the program path. */ - const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); - R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); - - /* Update the arguments, as needed. */ - if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { - R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size)); - } + bool IsValidProgramAttributes(const ldr::ProgramAttributes &attrs) { + /* Check that the attributes are valid; on NX, this means Platform = NX + no content attrs. */ + if (attrs.platform != ncm::ContentMetaPlatform::Nx) { + return false; + } + if (attrs.content_attributes != fs::ContentAttributes_None) { + return false; } - /* If we should, set the output status. */ - if (out_status != nullptr) { - *out_status = status; - } - - R_SUCCEED(); + return true; } } - Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) { - R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, PlatformId_Nx)); + Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs) { + /* Check that the program attributes are valid. */ + R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes()); + + /* Get the location and override status. */ + ncm::ProgramLocation loc; + cfg::OverrideStatus override_status; + R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + path[sizeof(path) - 1] = '\x00'; + + /* Create the process. */ + R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, attrs)); } - Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { - R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, PlatformId_Nx)); + Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + /* Check that the program attributes are valid. */ + R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes()); + + /* Zero output. */ + std::memset(out, 0, sizeof(*out)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + path[sizeof(path) - 1] = '\x00'; + + /* Get the program info. */ + cfg::OverrideStatus status; + R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, attrs)); + + if (loc.program_id != out->program_id) { + /* Redirect the program path. */ + const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); + R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); + + /* Update the arguments, as needed. */ + if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { + R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size)); + } + } + + /* If we should, set the output status. */ + if (out_status != nullptr) { + *out_status = status; + } + + R_SUCCEED(); } Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { diff --git a/stratosphere/loader/source/ldr_loader_service.hpp b/stratosphere/loader/source/ldr_loader_service.hpp index bad74cd80..9f5314c55 100644 --- a/stratosphere/loader/source/ldr_loader_service.hpp +++ b/stratosphere/loader/source/ldr_loader_service.hpp @@ -21,16 +21,16 @@ namespace ams::ldr { class LoaderService { public: /* Official commands. */ - Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h) { + Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ProgramAttributes &attrs) { /* Create a handle to set the output to when done. */ os::NativeHandle handle = os::InvalidNativeHandle; ON_SCOPE_EXIT { proc_h.SetValue(handle, true); }; - R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle())); + R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle(), attrs)); } - Result GetProgramInfo(sf::Out out_program_info, const ncm::ProgramLocation &loc) { - R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc)); + Result GetProgramInfo(sf::Out out_program_info, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc, attrs)); } Result PinProgram(sf::Out out_id, const ncm::ProgramLocation &loc) { @@ -75,16 +75,16 @@ namespace ams::ldr { return this->HasLaunchedBootProgram(out.GetPointer(), program_id); } - Result AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc) { - R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc)); + Result AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc, attrs)); } Result AtmospherePinProgram(sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status) { R_RETURN(this->PinProgram(out_id.GetPointer(), loc, override_status)); } private: - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); Result SetProgramArgument(ncm::ProgramId program_id, const void *argument, size_t size); Result GetProcessModuleInfo(u32 *out_count, ModuleInfo *out, size_t max_out_count, os::ProcessId process_id); diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index 5b6001f93..5e4d8ca06 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -46,7 +46,7 @@ namespace ams { namespace { struct ServerOptions { - static constexpr size_t PointerBufferSize = 0x400; + static constexpr size_t PointerBufferSize = 0x420; static constexpr size_t MaxDomains = 0; static constexpr size_t MaxDomainObjects = 0; static constexpr bool CanDeferInvokeRequest = false; diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index 236755c05..04e71d38b 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -103,17 +103,17 @@ namespace ams::ldr { R_SUCCEED(); } - const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) { + const u8 *GetAcidSignatureModulus(ncm::ContentMetaPlatform platform, u8 key_generation, bool unk_unused) { return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused); } - size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) { + size_t GetAcidSignatureModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused); } - Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) { + Result ValidateAcidSignature(Meta *meta, ncm::ContentMetaPlatform platform, bool unk_unused) { /* Loader did not check signatures prior to 10.0.0. */ - { + if (hos::GetVersion() < hos::Version_10_0_0) { meta->check_verification_data = false; R_SUCCEED(); } @@ -190,7 +190,7 @@ namespace ams::ldr { } /* API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) { + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform, bool unk_unused) { /* Set the cached program id back to zero. */ g_cached_program_id = {}; @@ -252,6 +252,10 @@ namespace ams::ldr { meta->npdm->main_thread_priority = HblMainThreadPriorityApplet; } } + + /* Fix the debug capabilities, to prevent needing a hbl recompilation. */ + FixDebugCapabilityForHbl(static_cast(meta->acid_kac), meta->acid->kac_size / sizeof(util::BitPack32)); + FixDebugCapabilityForHbl(static_cast(meta->aci_kac), meta->aci->kac_size / sizeof(util::BitPack32)); } else if (hos::GetVersion() >= hos::Version_10_0_0) { /* If storage id is none, there is no base code filesystem, and thus it is impossible for us to validate. */ /* However, if we're an application, we are guaranteed a base code filesystem. */ @@ -278,7 +282,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) { + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform) { if (g_cached_program_id != loc.program_id || g_cached_override_status != status) { R_RETURN(LoadMeta(out_meta, loc, status, platform, false)); } diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp index 2ac88b63b..4d3ce3fb8 100644 --- a/stratosphere/loader/source/ldr_meta.hpp +++ b/stratosphere/loader/source/ldr_meta.hpp @@ -36,8 +36,8 @@ namespace ams::ldr { }; /* Meta API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused); - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform); + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform, bool unk_unused); + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform); void InvalidateMetaCache(); } diff --git a/stratosphere/loader/source/ldr_patcher.cpp b/stratosphere/loader/source/ldr_patcher.cpp index 9671e1cd2..a014067c6 100644 --- a/stratosphere/loader/source/ldr_patcher.cpp +++ b/stratosphere/loader/source/ldr_patcher.cpp @@ -107,9 +107,6 @@ namespace ams::ldr { const EmbeddedPatchEntry *entries; }; - #include "ldr_embedded_es_patches.inc" - #include "ldr_embedded_nifm_patches.inc" - #include "ldr_embedded_nim_patches.inc" #include "ldr_embedded_usb_patches.inc" } @@ -143,38 +140,6 @@ namespace ams::ldr { } } } - - for (const auto &patch : DisableTicketVerificationPatches) { - if (std::memcmp(std::addressof(patch.module_id), std::addressof(module_id), sizeof(module_id)) == 0) { - for (size_t i = 0; i < patch.num_entries; ++i) { - const auto &entry = patch.entries[i]; - if (entry.offset + entry.size <= mapped_size) { - std::memcpy(reinterpret_cast(mapped_nso + entry.offset), entry.data, entry.size); - } - } - } - } - - for (const auto &patch : ForceCommunicationEnabledPatches) { - if (std::memcmp(std::addressof(patch.module_id), std::addressof(module_id), sizeof(module_id)) == 0) { - for (size_t i = 0; i < patch.num_entries; ++i) { - const auto &entry = patch.entries[i]; - if (entry.offset + entry.size <= mapped_size) { - std::memcpy(reinterpret_cast(mapped_nso + entry.offset), entry.data, entry.size); - } - } - } - } - - for (const auto &patch : AmsProdinfoBlankerFix) { - if (std::memcmp(std::addressof(patch.module_id), std::addressof(module_id), sizeof(module_id)) == 0) { - for (size_t i = 0; i < patch.num_entries; ++i) { - const auto &entry = patch.entries[i]; - if (entry.offset + entry.size <= mapped_size) { - std::memcpy(reinterpret_cast(mapped_nso + entry.offset), entry.data, entry.size); - } - } - } - } } + } \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index a7d657897..5f6f2226b 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -555,7 +555,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size) { + Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size, bool prevent_code_reads) { /* Map and read data from file. */ { /* Map the process memory. */ @@ -594,7 +594,7 @@ namespace ams::ldr { const size_t ro_size = util::AlignUp(nso_header->ro_size, os::MemoryPageSize); const size_t rw_size = util::AlignUp(nso_header->rw_size + nso_header->bss_size, os::MemoryPageSize); if (text_size) { - R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->text_dst_offset, text_size, os::MemoryPermission_ReadExecute)); + R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->text_dst_offset, text_size, prevent_code_reads ? os::MemoryPermission_ExecuteOnly : os::MemoryPermission_ReadExecute)); } if (ro_size) { R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->ro_dst_offset, ro_size, os::MemoryPermission_ReadOnly)); @@ -606,7 +606,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument) { + Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument, bool prevent_code_reads) { /* Load each NSO. */ for (size_t i = 0; i < Nso_Count; i++) { if (has_nso[i]) { @@ -614,7 +614,7 @@ namespace ams::ldr { R_TRY(fs::OpenFile(std::addressof(file), GetNsoPath(i), fs::OpenMode_Read)); ON_SCOPE_EXIT { fs::CloseFile(file); }; - R_TRY(LoadAutoLoadModule(process_info->process_handle, file, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i])); + R_TRY(LoadAutoLoadModule(process_info->process_handle, file, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i], prevent_code_reads)); } } @@ -658,21 +658,21 @@ namespace ams::ldr { ON_RESULT_FAILURE { svc::CloseHandle(process_handle); }; /* Load all auto load modules. */ - R_RETURN(LoadAutoLoadModules(out, nso_headers, has_nso, argument)); + R_RETURN(LoadAutoLoadModules(out, nso_headers, has_nso, argument, (meta->npdm->flags & ldr::Npdm::MetaFlag_PreventCodeReads) != 0)); } } /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs) { /* Mount code. */ AMS_UNUSED(path); - ScopedCodeMount mount(loc, override_status, platform); + ScopedCodeMount mount(loc, override_status, attrs); R_TRY(mount.GetResult()); /* Load meta, possibly from cache. */ Meta meta; - R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform)); + R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, attrs.platform)); /* Validate meta. */ R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData())); @@ -720,16 +720,16 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform) { + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs) { Meta meta; /* Load Meta. */ { AMS_UNUSED(path); - ScopedCodeMount mount(loc, platform); + ScopedCodeMount mount(loc, attrs); R_TRY(mount.GetResult()); - R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false)); + R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), attrs.platform, false)); if (out_status != nullptr) { *out_status = mount.GetOverrideStatus(); } diff --git a/stratosphere/loader/source/ldr_process_creation.hpp b/stratosphere/loader/source/ldr_process_creation.hpp index 79a622169..0d24c7720 100644 --- a/stratosphere/loader/source/ldr_process_creation.hpp +++ b/stratosphere/loader/source/ldr_process_creation.hpp @@ -19,8 +19,8 @@ namespace ams::ldr { /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs); Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); Result UnpinProgram(PinId id); diff --git a/stratosphere/memlet/Makefile b/stratosphere/memlet/Makefile new file mode 100644 index 000000000..d681240e5 --- /dev/null +++ b/stratosphere/memlet/Makefile @@ -0,0 +1,41 @@ +ATMOSPHERE_BUILD_CONFIGS := +all: nx_release + +THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) +CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) + +define ATMOSPHERE_ADD_TARGET + +ATMOSPHERE_BUILD_CONFIGS += $(strip $1) + +$(strip $1): + @echo "Building $(strip $1)" + @$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) + +clean-$(strip $1): + @echo "Cleaning $(strip $1)" + @$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk clean ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) + +endef + +define ATMOSPHERE_ADD_TARGETS + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_release, release, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4)" \ +)) + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_debug, debug, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_DEBUGGING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 \ +)) + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_audit, audit, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_AUDITING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 ATMOSPHERE_BUILD_FOR_AUDITING=1 \ +)) + +endef + +$(eval $(call ATMOSPHERE_ADD_TARGETS, nx, nx-hac-001, arm-cortex-a57,)) + +clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config)) + +.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS), $(config) clean-$(config)) diff --git a/stratosphere/memlet/memlet.json b/stratosphere/memlet/memlet.json new file mode 100644 index 000000000..8f44c0ce2 --- /dev/null +++ b/stratosphere/memlet/memlet.json @@ -0,0 +1,93 @@ +{ + "name": "memlet", + "title_id": "0x0100000000000421", + "title_id_range_min": "0x0100000000000421", + "title_id_range_max": "0x0100000000000421", + "main_thread_stack_size": "0x00002000", + "main_thread_priority": 44, + "default_cpu_id": 3, + "process_category": 0, + "is_retail": true, + "pool_partition": 1, + "is_64_bit": true, + "address_space_type": 3, + "disable_device_address_space_merge": true, + "filesystem_access": { + "permissions": "0xFFFFFFFFFFFFFFFF" + }, + "service_access": ["fatal:u"], + "service_host": ["memlet"], + "kernel_capabilities": [{ + "type": "kernel_flags", + "value": { + "highest_thread_priority": 63, + "lowest_thread_priority": 24, + "lowest_cpu_id": 3, + "highest_cpu_id": 3 + } + }, { + "type": "syscalls", + "value": { + "svcSetHeapSize": "0x01", + "svcSetMemoryPermission": "0x02", + "svcSetMemoryAttribute": "0x03", + "svcMapMemory": "0x04", + "svcUnmapMemory": "0x05", + "svcQueryMemory": "0x06", + "svcExitProcess": "0x07", + "svcCreateThread": "0x08", + "svcStartThread": "0x09", + "svcExitThread": "0x0a", + "svcSleepThread": "0x0b", + "svcGetThreadPriority": "0x0c", + "svcSetThreadPriority": "0x0d", + "svcGetThreadCoreMask": "0x0e", + "svcSetThreadCoreMask": "0x0f", + "svcGetCurrentProcessorNumber": "0x10", + "svcSignalEvent": "0x11", + "svcClearEvent": "0x12", + "svcMapSharedMemory": "0x13", + "svcUnmapSharedMemory": "0x14", + "svcCreateTransferMemory": "0x15", + "svcCloseHandle": "0x16", + "svcResetSignal": "0x17", + "svcWaitSynchronization": "0x18", + "svcCancelSynchronization": "0x19", + "svcArbitrateLock": "0x1a", + "svcArbitrateUnlock": "0x1b", + "svcWaitProcessWideKeyAtomic": "0x1c", + "svcSignalProcessWideKey": "0x1d", + "svcGetSystemTick": "0x1e", + "svcConnectToNamedPort": "0x1f", + "svcSendSyncRequestLight": "0x20", + "svcSendSyncRequest": "0x21", + "svcSendSyncRequestWithUserBuffer": "0x22", + "svcSendAsyncRequestWithUserBuffer": "0x23", + "svcGetProcessId": "0x24", + "svcGetThreadId": "0x25", + "svcBreak": "0x26", + "svcOutputDebugString": "0x27", + "svcReturnFromException": "0x28", + "svcGetInfo": "0x29", + "svcWaitForAddress": "0x34", + "svcSignalToAddress": "0x35", + "svcSynchronizePreemptionState": "0x36", + "svcCreateSession": "0x40", + "svcAcceptSession": "0x41", + "svcReplyAndReceiveLight": "0x42", + "svcReplyAndReceive": "0x43", + "svcReplyAndReceiveWithUserBuffer": "0x44", + "svcCreateSharedMemory": "0x50", + "svcCallSecureMonitor": "0x7f" + } + }, { + "type": "application_type", + "value": 2 + }, { + "type": "min_kernel_version", + "value": "0x0030" + }, { + "type": "handle_table_size", + "value": 0 + }] +} \ No newline at end of file diff --git a/stratosphere/memlet/source/memlet_main.cpp b/stratosphere/memlet/source/memlet_main.cpp new file mode 100644 index 000000000..ea0ee7c10 --- /dev/null +++ b/stratosphere/memlet/source/memlet_main.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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 . + */ +#include +#include "memlet_service.hpp" + +namespace ams { + + namespace memlet { + + namespace { + + using ServerOptions = sf::hipc::DefaultServerManagerOptions; + + constexpr sm::ServiceName MemServiceName = sm::ServiceName::Encode("memlet"); + constexpr size_t MemMaxSessions = 1; + + /* memlet. */ + constexpr size_t NumServers = 1; + constexpr size_t NumSessions = MemMaxSessions; + + sf::hipc::ServerManager g_server_manager; + + constinit sf::UnmanagedServiceObject g_mem_service_object; + + void InitializeAndLoopIpcServer() { + /* Create services. */ + R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_mem_service_object.GetShared(), MemServiceName, MemMaxSessions)); + + /* Loop forever, servicing our services. */ + g_server_manager.LoopProcess(); + } + + } + + } + + namespace init { + + void InitializeSystemModule() { + /* Initialize our connection to sm. */ + R_ABORT_UNLESS(sm::Initialize()); + + /* Verify that we can sanely execute. */ + ams::CheckApiVersion(); + } + + void FinalizeSystemModule() { /* ... */ } + + void Startup() { /* ... */ } + + } + + void Main() { + /* Set thread name. */ + os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(memlet, Main)); + AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(memlet, Main)); + + /* Initialize and service our ipc service. */ + memlet::InitializeAndLoopIpcServer(); + } + +} diff --git a/stratosphere/memlet/source/memlet_service.cpp b/stratosphere/memlet/source/memlet_service.cpp new file mode 100644 index 000000000..ffccc6e8e --- /dev/null +++ b/stratosphere/memlet/source/memlet_service.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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 . + */ +#include +#include "memlet_service.hpp" + +namespace ams::memlet { + + Result Service::CreateAppletSharedMemory(sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size) { + /* Create a handle to set the output to when done. */ + os::NativeHandle handle = os::InvalidNativeHandle; + ON_SCOPE_EXIT { out_handle.SetValue(handle, true); }; + + /* Check that the requested size has megabyte alignment and isn't too big. */ + R_UNLESS(util::IsAligned(desired_size, 1_MB), os::ResultInvalidParameter()); + R_UNLESS(desired_size <= 128_MB, os::ResultInvalidParameter()); + + /* Try to create a shared memory of the desired size, giving up 1 MB each iteration. */ + os::SharedMemoryType shmem = {}; + while (true) { + /* If we have zero desired-size left, we've failed. */ + R_UNLESS(desired_size > 0, os::ResultOutOfMemory()); + + /* Try to create a shared memory. */ + if (R_FAILED(os::CreateSharedMemory(std::addressof(shmem), desired_size, os::MemoryPermission_ReadWrite, os::MemoryPermission_ReadWrite))) { + /* We failed, so decrease the size to see if that works. */ + desired_size -= 1_MB; + continue; + } + + /* We successfully created the shared memory. */ + break; + } + + /* Get the native handle for the shared memory we created. */ + handle = os::GetSharedMemoryHandle(std::addressof(shmem)); + + /* HACK: Clear the shared memory object, since we've stolen its handle, and there's no "correct" way to detach. */ + shmem = {}; + + /* We successfully created a shared memory! */ + *out_size = desired_size; + R_SUCCEED(); + } + +} diff --git a/stratosphere/memlet/source/memlet_service.hpp b/stratosphere/memlet/source/memlet_service.hpp new file mode 100644 index 000000000..6d003753e --- /dev/null +++ b/stratosphere/memlet/source/memlet_service.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 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 . + */ +#pragma once +#include + +#define AMS_MEMLET_I_SERVICE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 65000, Result, CreateAppletSharedMemory, (sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size), (out_size, out_handle, desired_size)) + +AMS_SF_DEFINE_INTERFACE(ams::memlet::impl, IService, AMS_MEMLET_I_SERVICE_INTERFACE_INFO, 0x00000000) + +namespace ams::memlet { + + class Service { + public: + Result CreateAppletSharedMemory(sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size); + }; + static_assert(impl::IsIService); + +} diff --git a/stratosphere/memlet/system_module.mk b/stratosphere/memlet/system_module.mk new file mode 100644 index 000000000..d6de42efc --- /dev/null +++ b/stratosphere/memlet/system_module.mk @@ -0,0 +1,131 @@ +#--------------------------------------------------------------------------------- +# pull in common stratosphere sysmodule configuration +#--------------------------------------------------------------------------------- +THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) +CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) +include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk + +ATMOSPHERE_SYSTEM_MODULE_TARGETS := nsp + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(__RECURSIVE__),1) +#--------------------------------------------------------------------------------- + +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) +CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) +SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) + +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(AMS_LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(foreach dir,$(AMS_LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR)) + +export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) + +ifeq ($(strip $(CONFIG_JSON)),) + jsons := $(wildcard *.json) + ifneq (,$(findstring $(TARGET).json,$(jsons))) + export APP_JSON := $(TOPDIR)/$(TARGET).json + else + ifneq (,$(findstring config.json,$(jsons))) + export APP_JSON := $(TOPDIR)/config.json + endif + endif +else + export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) +endif + +.PHONY: clean all check_lib + +#--------------------------------------------------------------------------------- +all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a + @$(MAKE) __RECURSIVE__=1 OUTPUT=$(CURDIR)/$(ATMOSPHERE_OUT_DIR)/$(TARGET) \ + DEPSDIR=$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) \ + --no-print-directory -C $(ATMOSPHERE_BUILD_DIR) \ + -f $(THIS_MAKEFILE) + +$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib + @$(SILENTCMD)echo "Checked library." + +ifeq ($(ATMOSPHERE_CHECKED_LIBSTRATOSPHERE),1) +check_lib: +else +check_lib: + @$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/libstratosphere.mk +endif + +$(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR): + @[ -d $@ ] || mkdir -p $@ + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) + + +#--------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +all : $(foreach target,$(ATMOSPHERE_SYSTEM_MODULE_TARGETS),$(OUTPUT).$(target)) + +$(OUTPUT).kip : $(OUTPUT).elf +$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm +$(OUTPUT).nso : $(OUTPUT).elf + +$(OUTPUT).elf : $(OFILES) + +$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a + +%.npdm : %.npdm.json + @echo built ... $< $@ + @npdmtool $< $@ + @echo built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index 005504b72..4ffe5e94e 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -85,6 +85,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } } diff --git a/stratosphere/pm/source/impl/pm_process_attributes.hpp b/stratosphere/pm/source/impl/pm_process_attributes.hpp new file mode 100644 index 000000000..b622be264 --- /dev/null +++ b/stratosphere/pm/source/impl/pm_process_attributes.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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 . + */ +#pragma once +#include + +namespace ams::pm::impl { + + struct ProcessAttributes { + u8 unknown[3]; + ldr::ProgramAttributes program_attrs; + }; + static_assert(sizeof(ProcessAttributes) == 5); + + constexpr inline ProcessAttributes ProcessAttributes_Nx = { + .unknown = {}, + .program_attrs = { + .platform = ncm::ContentMetaPlatform::Nx, + .content_attributes = fs::ContentAttributes_None, + }, + }; + +} diff --git a/stratosphere/pm/source/impl/pm_process_info.cpp b/stratosphere/pm/source/impl/pm_process_info.cpp index 90373b55a..d472803dc 100644 --- a/stratosphere/pm/source/impl/pm_process_info.cpp +++ b/stratosphere/pm/source/impl/pm_process_info.cpp @@ -76,7 +76,7 @@ namespace ams::pm::impl { } - ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0) { + ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s, const ProcessAttributes &attrs) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0), m_attrs(attrs) { os::InitializeMultiWaitHolder(std::addressof(m_multi_wait_holder), m_handle); os::SetMultiWaitHolderUserData(std::addressof(m_multi_wait_holder), reinterpret_cast(this)); } @@ -106,8 +106,8 @@ namespace ams::pm::impl { return ProcessListAccessor(g_exit_list); } - ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status) { - return g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status); + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status, const ProcessAttributes &attrs) { + return g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status, attrs); } void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index f2dae02ae..66e64c436 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -15,6 +15,7 @@ */ #pragma once #include "pm_process_manager.hpp" +#include "pm_process_attributes.hpp" namespace ams::pm::impl { @@ -46,6 +47,7 @@ namespace ams::pm::impl { os::NativeHandle m_handle; svc::ProcessState m_state; u32 m_flags; + ProcessAttributes m_attrs; os::MultiWaitHolderType m_multi_wait_holder; private: void SetFlag(Flag flag) { @@ -60,7 +62,7 @@ namespace ams::pm::impl { return (m_flags & flag); } public: - ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s); + ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s, const ProcessAttributes &attrs); ~ProcessInfo(); void Cleanup(); @@ -88,6 +90,10 @@ namespace ams::pm::impl { return m_status; } + const ProcessAttributes &GetProcessAttributes() const { + return m_attrs; + } + svc::ProcessState GetState() const { return m_state; } @@ -235,7 +241,7 @@ namespace ams::pm::impl { ProcessListAccessor GetProcessList(); ProcessListAccessor GetExitList(); - ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status); + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status, const ProcessAttributes &attrs); void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info); } diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 32ef0feac..8a4d7ba16 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -117,14 +117,14 @@ namespace ams::pm::impl { R_SUCCEED(); } - Result LaunchProgramImpl(ProcessInfo **out_process_info, os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { + Result LaunchProgramImpl(ProcessInfo **out_process_info, os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags, const ProcessAttributes &attrs) { /* Set the output to nullptr, if we fail. */ *out_process_info = nullptr; /* Get Program Info. */ ldr::ProgramInfo program_info; cfg::OverrideStatus override_status; - R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), loc)); + R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), loc, attrs.program_attrs)); const bool is_application = (program_info.flags & ldr::ProgramInfoFlag_ApplicationTypeMask) == ldr::ProgramInfoFlag_Application; const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || hos::GetVersion() < hos::Version_2_0_0; @@ -166,14 +166,14 @@ namespace ams::pm::impl { WaitResourceAvailable(std::addressof(program_info)); /* Actually create the process. */ - R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)))); + R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)), attrs.program_attrs)); } /* Get the process id. */ os::ProcessId process_id = os::GetProcessId(process_handle); /* Make new process info. */ - ProcessInfo *process_info = AllocateProcessInfo(process_handle, process_id, pin_id, fixed_location, override_status); + ProcessInfo *process_info = AllocateProcessInfo(process_handle, process_id, pin_id, fixed_location, override_status, attrs); AMS_ABORT_UNLESS(process_info != nullptr); /* Add the new process info to the process list. */ @@ -195,7 +195,7 @@ namespace ams::pm::impl { const u8 *aci_fah = acid_fac + program_info.acid_fac_size; /* Register with FS and SM. */ - R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(fixed_location.program_id), static_cast(fixed_location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size)); + R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(fixed_location.program_id), static_cast(fixed_location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size, 0)); R_TRY(sm::manager::RegisterProcess(process_id, fixed_location.program_id, override_status, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size)); /* Set flags. */ @@ -253,7 +253,7 @@ namespace ams::pm::impl { Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { /* Launch the program. */ ProcessInfo *process_info = nullptr; - R_TRY(LaunchProgramImpl(std::addressof(process_info), out_process_id, loc, flags)); + R_TRY(LaunchProgramImpl(std::addressof(process_info), out_process_id, loc, flags, ProcessAttributes_Nx)); /* Register the process info with the tracker. */ g_process_tracker.QueueEntry(process_info); @@ -268,7 +268,7 @@ namespace ams::pm::impl { R_UNLESS(!process_info->HasStarted(), pm::ResultAlreadyStarted()); ldr::ProgramInfo program_info; - R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation())); + R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation(), process_info->GetProcessAttributes().program_attrs)); R_RETURN(StartProcess(process_info, std::addressof(program_info))); } diff --git a/stratosphere/pm/source/impl/pm_spec.cpp b/stratosphere/pm/source/impl/pm_spec.cpp index 9127d2e6a..ee0e38060 100644 --- a/stratosphere/pm/source/impl/pm_spec.cpp +++ b/stratosphere/pm/source/impl/pm_spec.cpp @@ -82,7 +82,7 @@ namespace ams::pm::impl { [svc::LimitableResource_ThreadCountMax] = BaseAppletThreads, [svc::LimitableResource_EventCountMax] = 0, [svc::LimitableResource_TransferMemoryCountMax] = 32, - [svc::LimitableResource_SessionCountMax] = 5, + [svc::LimitableResource_SessionCountMax] = 5 + 1, /* Add a session for atmosphere's memlet system module. */ }, }; diff --git a/stratosphere/pm/source/pm_boot_mode_service.cpp b/stratosphere/pm/source/pm_boot_mode_service.cpp index ff389fe75..a1a762d34 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.cpp +++ b/stratosphere/pm/source/pm_boot_mode_service.cpp @@ -22,6 +22,7 @@ namespace ams::pm { /* Global bootmode. */ constinit BootMode g_boot_mode = BootMode::Normal; + constinit u32 g_unknown = 0; } @@ -47,4 +48,14 @@ namespace ams::pm { pm::bm::SetMaintenanceBoot(); } + void BootModeService::GetUnknown(sf::Out out) { + out.SetValue(g_unknown); + } + + Result BootModeService::SetUnknown(u32 val) { + R_UNLESS(val <= 3, pm::ResultUnknown7()); + g_unknown = val; + R_SUCCEED(); + } + } diff --git a/stratosphere/pm/source/pm_boot_mode_service.hpp b/stratosphere/pm/source/pm_boot_mode_service.hpp index c650e9b47..b47536ed7 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.hpp +++ b/stratosphere/pm/source/pm_boot_mode_service.hpp @@ -22,6 +22,8 @@ namespace ams::pm { public: void GetBootMode(sf::Out out); void SetMaintenanceBoot(); + void GetUnknown(sf::Out out); + Result SetUnknown(u32 val); }; static_assert(pm::impl::IsIBootModeInterface); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index b7d775be9..5bef871c7 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -53,7 +53,7 @@ namespace ams { /* It also registers privileged processes with SM, so that their program ids can be known. */ void RegisterPrivilegedProcess(os::ProcessId process_id, ncm::ProgramId program_id) { fsprUnregisterProgram(process_id.value); - fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl)); + fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl), 0); sm::manager::UnregisterProcess(process_id); sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); } diff --git a/stratosphere/ro/source/impl/ro_nro_utils.cpp b/stratosphere/ro/source/impl/ro_nro_utils.cpp index 588a26387..3f01a1c99 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.cpp @@ -51,11 +51,15 @@ namespace ams::ro::impl { R_SUCCEED(); } - Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) { - const u64 rx_offset = 0; + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size, bool is_aligned_header) { + const u64 rx_offset = is_aligned_header ? os::MemoryPageSize : 0; const u64 ro_offset = rx_offset + rx_size; const u64 rw_offset = ro_offset + ro_size; + if (is_aligned_header) { + R_TRY(os::SetProcessMemoryPermission(process_handle, base_address, os::MemoryPageSize, os::MemoryPermission_ReadOnly)); + } + R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + rx_offset, rx_size, os::MemoryPermission_ReadExecute)); R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + ro_offset, ro_size, os::MemoryPermission_ReadOnly)); R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + rw_offset, rw_size, os::MemoryPermission_ReadWrite)); diff --git a/stratosphere/ro/source/impl/ro_nro_utils.hpp b/stratosphere/ro/source/impl/ro_nro_utils.hpp index df018c872..9ea2f7b32 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.hpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.hpp @@ -21,7 +21,7 @@ namespace ams::ro::impl { /* Utilities for working with NROs. */ Result MapNro(u64 *out_base_address, os::NativeHandle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size); - Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size); + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size, bool is_aligned_header); Result UnmapNro(os::NativeHandle process_handle, u64 base_address, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size); } \ No newline at end of file diff --git a/stratosphere/ro/source/impl/ro_service_impl.cpp b/stratosphere/ro/source/impl/ro_service_impl.cpp index 0be672f37..0eee275eb 100644 --- a/stratosphere/ro/source/impl/ro_service_impl.cpp +++ b/stratosphere/ro/source/impl/ro_service_impl.cpp @@ -247,7 +247,7 @@ namespace ams::ro::impl { R_THROW(ro::ResultNotAuthorized()); } - Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { + Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, bool *out_aligned_header, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { /* Map the NRO. */ void *mapped_memory = nullptr; R_TRY_CATCH(os::MapProcessMemory(std::addressof(mapped_memory), m_process_handle, base_address, expected_nro_size, ro::impl::GenerateSecureRandom)) { @@ -306,6 +306,7 @@ namespace ams::ro::impl { *out_rx_size = text_size; *out_ro_size = ro_size; *out_rw_size = rw_size; + *out_aligned_header = header->IsAlignedHeader(); R_SUCCEED(); } @@ -557,10 +558,11 @@ namespace ams::ro::impl { /* Validate the NRO (parsing region extents). */ u64 rx_size = 0, ro_size = 0, rw_size = 0; - R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), nro_info->base_address, nro_size, bss_size)); + bool aligned_header = false; + R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), std::addressof(aligned_header), nro_info->base_address, nro_size, bss_size)); /* Set NRO perms. */ - R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size)); + R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size, aligned_header)); context->SetNroInfoInUse(nro_info, true); nro_info->code_size = rx_size + ro_size; diff --git a/stratosphere/stratosphere.mk b/stratosphere/stratosphere.mk index 5b06a6d98..b20244ec6 100644 --- a/stratosphere/stratosphere.mk +++ b/stratosphere/stratosphere.mk @@ -5,7 +5,7 @@ THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) include $(CURRENT_DIRECTORY)/../libraries/config/common.mk -ALL_MODULES := loader boot ncm pm sm ams_mitm spl eclct.stub ro creport fatal dmnt boot2 erpt pgl jpegdec LogManager cs htc TioServer dmnt.gen2 +ALL_MODULES := loader boot ncm pm sm ams_mitm spl eclct.stub ro creport fatal dmnt boot2 erpt pgl jpegdec LogManager cs htc TioServer dmnt.gen2 memlet all: $(ALL_MODULES) diff --git a/utilities/erpt.py b/utilities/erpt.py index 94d0919cd..a69e6e915 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -238,7 +238,17 @@ CATEGORIES = { 139 : 'EthernetAdapterOUIInfo', 140 : 'NANDTypeInfo', 141 : 'MicroSDTypeInfo', + 142 : 'AttachmentFileInfo', + 143 : 'WlanInfo', + 144 : 'HalfAwakeStateInfo', + 145 : 'PctlSettingInfo', + 146 : 'GameCardLogInfo', + 147 : 'WlanIoctlErrorInfo', + 148 : 'SdCardActivationInfo', + 149 : 'GameCardDetailedErrorInfo', 1000 : 'TestNx', + 1001 : 'NANDTypeInfo', + 1002 : 'NANDExtendedCsd', } FIELD_TYPES = {