diff --git a/README.md b/README.md index aee0ff97d..2e3f1a7fd 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ ===== ![License](https://img.shields.io/badge/License-GPLv2-blue.svg) -[![Chat on Discord](https://img.shields.io/badge/Discord-5865f2?logo=discord&logoColor=white)](https://discordapp.com/invite/ZdqEhed) -![Made with Notepad++](img/np++.png?raw=true) +[![Chat on Discord](https://camo.githubusercontent.com/b4175720ede4f2621aa066ffbabb70ae30044679/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636861742d446973636f72642d627269676874677265656e2e737667)](https://discordapp.com/invite/ZdqEhed) Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. @@ -14,6 +13,7 @@ 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 @@ -27,6 +27,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec You can find a copy of the license in the [LICENSE file](LICENSE). Exemptions: +* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the Atmosphère project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects. * [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license. Credits diff --git a/atmosphere.mk b/atmosphere.mk index 846ca1c22..706b5f320 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -50,7 +50,6 @@ 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 @@ -85,10 +84,9 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037 - #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c + 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 @@ -100,13 +98,12 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/fatal/$(ATMOSPHERE_OUT_DIR)/fatal.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/creport/$(ATMOSPHERE_OUT_DIR)/creport.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp cp stratosphere/ro/$(ATMOSPHERE_OUT_DIR)/ro.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp - #cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp + cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp cp stratosphere/pgl/$(ATMOSPHERE_OUT_DIR)/pgl.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp cp stratosphere/LogManager/$(ATMOSPHERE_OUT_DIR)/LogManager.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420/exefs.nsp 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 8df772ccf..e8dc82377 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 will break Atmosphere. +# Disabling this may break Atmosphere's debugger in a future release. # Key: debugmode_user, default: 0. # Desc: Controls whether userland is debug mode. diff --git a/docs/changelog.md b/docs/changelog.md index 93e7e87fb..5f2c954fa 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,114 +1,4 @@ # Changelog -## 1.9.3 -+ Basic support was added for 20.3.0. -+ Compatibility was fixed for loading mods with KOTOR 2 (star wars). -+ General system stability improvements to enhance the user's experience. -## 1.9.2 -+ Basic support was added for 20.2.0. -+ USB 3.0 support force-enable was fixed for 20.1.0+. -+ General system stability improvements to enhance the user's experience. -## 1.9.1 -+ Basic support was added for 20.1.0. -+ General system stability improvements to enhance the user's experience. -## 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). -+ Further changes were for 18.0.0: - + `loader` was updated to reflect the latest official behavior. -+ General system stability improvements to enhance the user's experience. -## 1.7.0 -+ Basic support was added for 18.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, once I am not traveling so much. - + `exosphère` was updated to reflect the latest official secure monitor behavior. - + `mesosphère` was updated to reflect the latest official kernel behavior. - + `spl` was updated to reflect the latest official behavior. -+ `fusee`'s no longer supports applying IPS patches to KIPs. - + The only KIPs that are ever present are a) atmosphère modules, b) custom system modules, or c) FS. - + The IPS subsystem was originally designed to make nogc patches work for FS, but these are now internal, and it appears the literal only kip patches that exist are for piracy. - + I could not find any kip patches posted anywhere made for any other purpose. - + It fundamentally does not make sense to slow down boot for every normal user for a feature that has no actual use-case, especially when `fusee` seeks to be a minimal bootloader. -+ Minor improvements were made to atmosphere's gdbstub, including: - + Support was added for QStartNoAckMode. - + An issue was fixed that could cause a fatal error when creating too many breakpoints. -+ A number of minor issues were fixed and improvements were made, including: - + `pt-BR` (`PortugueseBr`) is now accepted as a valid language when overriding game locales. - + A bug was fixed that could cause atmosphere to incorrectly serialize output object IDs over IPC when using domain objects. - + A bug was fixed in `pm`'s resource limit boost logic that could potentially cause legitimate boosts to fail in certain circumstances. - + `loader`/`ro` will now throw a fatal error when using invalid IPS patches that go out of bounds, instead of corrupting memory. - + Support was fixed for booting using a memory configuration of half of the true available memory (e.g. forcing a 4GB configuration on an 8GB board). -+ General system stability improvements to enhance the user's experience. -## 1.6.2 -+ Support was finished for 17.0.0. - + `erpt` was updated to support the latest official behavior. - + `jpegdec` was updated to support the latest official behavior. - + `pm` was updated to support the latest official behavior. -+ General system stability improvements to enhance the user's experience. -## 1.6.1 -+ An improved solution to [the problem that would cause consoles which had previously re-built their SYSTEM partition to brick on update-to-17.0.0](https://gist.github.com/SciresM/2ddb708c812ed585c4d99f54e25205ff) was added. - + In particular, booting atmosphère will now automatically detect the problem and unbrick any consoles which have fallen into this state. -+ Some improvements were made to `haze`, including: - + Performance was greatly improved: - + Support was added for GetObjectPropList, which decreases the amount of requests made by ~8x. - + Haze now performs rendering on the GPU, freeing up the CPU to respond to requests in a more timely manner. - + An issue was fixed with how `haze` configures `bMaxPacketSize0` which improves support for USB3. -+ General system stability improvements to enhance the user's experience. -## 1.6.0 -+ Basic support was added for 17.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 soon-to-come atmosphère update. - + `exosphère` was updated to reflect the latest official secure monitor behavior. - + `mesosphère` was updated to reflect the latest official kernel behavior. - + `ncm` was updated to reflect the latest official behavior. - + `erpt` was partially updated to support the latest official behavior. -+ Atmosphere's gdbstub now supports waiting to attach to a specific program id on launch (as opposed to any application). - + The monitor command for this is `monitor wait `, where program id can optionally have an `0x` prefix. -+ Support was added to `haze` for editing files in-place and performing 64-bit transfers (files larger than 4 GB). -+ `bpc.mitm` was enabled on Mariko units, and now triggers pmic-based shutdowns/reboots (thanks @CTCaer). - + This should cause the console to no longer wake ~15 seconds after shutdown on Mariko. -+ A number of minor issues were fixed and improvements were made, including: - + A workaround was added for a change in 17.0.0 that would cause consoles which had previously re-built their SYSTEM partition to brick on update-to-17.0.0. -+ General system stability improvements to enhance the user's experience. ## 1.5.5 + Support was added for 16.1.0. + General system stability improvements to enhance the user's experience. diff --git a/docs/features/cheats.md b/docs/features/cheats.md index 465ded946..f67236bba 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, 4 = non-relative). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). + 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,13 +62,11 @@ 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 -`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` +`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` -+ 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). ++ 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). + 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. @@ -80,9 +78,6 @@ 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 @@ -131,7 +126,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, 4 = non-relative). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). + R: Register to load value into. + A: Immediate offset to use from memory region base. @@ -142,22 +137,6 @@ 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 @@ -271,10 +250,7 @@ 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 @@ -404,61 +380,6 @@ 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()`. - -+ 00000000 00000001: A -+ 00000000 00000002: B -+ 00000000 00000004: X -+ 00000000 00000008: Y -+ 00000000 00000010: Left Stick Pressed -+ 00000000 00000020: Right Stick Pressed -+ 00000000 00000040: L -+ 00000000 00000080: R -+ 00000000 00000100: ZL -+ 00000000 00000200: ZR -+ 00000000 00000400: Plus -+ 00000000 00000800: Minus -+ 00000000 00001000: Left -+ 00000000 00002000: Up -+ 00000000 00004000: Right -+ 00000000 00008000: Down -+ 00000000 00010000: Left Stick Left -+ 00000000 00020000: Left Stick Up -+ 00000000 00040000: Left Stick Right -+ 00000000 00080000: Left Stick Down -+ 00000000 00100000: Right Stick Left -+ 00000000 00200000: Right Stick Up -+ 00000000 00400000: Right Stick Right -+ 00000000 00800000: Right Stick Down -+ 00000000 01000000: SL Left Joy-Con -+ 00000000 02000000: SR Left Joy-Con -+ 00000000 04000000: SL Right Joy-Con -+ 00000000 08000000: SR Right Joy-Con -+ 00000000 10000000: Top button on Poké Ball Plus (Palma) controller -+ 00000000 20000000: Verification -+ 00000000 40000000: B button on Left NES/HVC controller in Handheld mode -+ 00000000 80000000: Left C button in N64 controller -+ 00000001 00000000: Up C button in N64 controller -+ 00000002 00000000: Right C button in N64 controller -+ 00000004 00000000: 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 1aad635a5..552875724 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = a8e5f1a184aeb8ba884166a1e4f386088d4a6cf1 - parent = 409c3cf9e190dbb65fe76570954939cbe8a5eca0 + commit = 30205111ee375bef96f0f76cb6a3130a2f0fc85c + parent = 81e9154a52a976f85317bddd0131426599d26a62 method = merge cmdver = 0.4.1 diff --git a/emummc/README.md b/emummc/README.md index aa9736d27..95a6a047a 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 - 20.1.0** +**1.0.0 - 16.0.3** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index 0db07fe8e..cf4c5dde5 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -67,18 +67,6 @@ #include "offsets/1600_exfat.h" #include "offsets/1603.h" #include "offsets/1603_exfat.h" -#include "offsets/1700.h" -#include "offsets/1700_exfat.h" -#include "offsets/1800.h" -#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 "offsets/2010.h" -#include "offsets/2010_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -157,18 +145,6 @@ DEFINE_OFFSET_STRUCT(_1600); DEFINE_OFFSET_STRUCT(_1600_EXFAT); DEFINE_OFFSET_STRUCT(_1603); DEFINE_OFFSET_STRUCT(_1603_EXFAT); -DEFINE_OFFSET_STRUCT(_1700); -DEFINE_OFFSET_STRUCT(_1700_EXFAT); -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); -DEFINE_OFFSET_STRUCT(_2010); -DEFINE_OFFSET_STRUCT(_2010_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -274,30 +250,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1603)); case FS_VER_16_0_3_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1603_EXFAT)); - case FS_VER_17_0_0: - return &(GET_OFFSET_STRUCT_NAME(_1700)); - case FS_VER_17_0_0_EXFAT: - return &(GET_OFFSET_STRUCT_NAME(_1700_EXFAT)); - case FS_VER_18_0_0: - return &(GET_OFFSET_STRUCT_NAME(_1800)); - case FS_VER_18_0_0_EXFAT: - return &(GET_OFFSET_STRUCT_NAME(_1800_EXFAT)); - case FS_VER_18_1_0: - 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)); - case FS_VER_20_1_0: - return &(GET_OFFSET_STRUCT_NAME(_2010)); - case FS_VER_20_1_0_EXFAT: - return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index 312f63224..a8459bf88 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -98,24 +98,6 @@ enum FS_VER FS_VER_16_0_3, FS_VER_16_0_3_EXFAT, - FS_VER_17_0_0, - FS_VER_17_0_0_EXFAT, - - FS_VER_18_0_0, - FS_VER_18_0_0_EXFAT, - - 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_20_1_0, - FS_VER_20_1_0_EXFAT, - FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1700.h b/emummc/source/FS/offsets/1700.h deleted file mode 100644 index 7a9cf825e..000000000 --- a/emummc/source/FS/offsets/1700.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1700_H__ -#define __FS_1700_H__ - -// Accessor vtable getters -#define FS_OFFSET_1700_SDMMC_ACCESSOR_GC 0x18AD00 -#define FS_OFFSET_1700_SDMMC_ACCESSOR_SD 0x18C9D0 -#define FS_OFFSET_1700_SDMMC_ACCESSOR_NAND 0x18B1D0 - -// Hooks -#define FS_OFFSET_1700_SDMMC_WRAPPER_READ 0x186BC0 -#define FS_OFFSET_1700_SDMMC_WRAPPER_WRITE 0x186C20 -#define FS_OFFSET_1700_RTLD 0x29D10 -#define FS_OFFSET_1700_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C))) - -#define FS_OFFSET_1700_CLKRST_SET_MIN_V_CLK_RATE 0x1A7B60 - -// Misc funcs -#define FS_OFFSET_1700_LOCK_MUTEX 0x17FEA0 -#define FS_OFFSET_1700_UNLOCK_MUTEX 0x17FEF0 - -#define FS_OFFSET_1700_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186B80 -#define FS_OFFSET_1700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186BA0 - -// Misc Data -#define FS_OFFSET_1700_SD_MUTEX 0xFCE3F0 -#define FS_OFFSET_1700_NAND_MUTEX 0xFC9B78 -#define FS_OFFSET_1700_ACTIVE_PARTITION 0xFC9BB8 -#define FS_OFFSET_1700_SDMMC_DAS_HANDLE 0xFAF840 - -// NOPs -#define FS_OFFSET_1700_SD_DAS_INIT 0x28C64 - -// Nintendo Paths -#define FS_OFFSET_1700_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068068, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x0007510C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007BEAC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0008F674, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1700_H__ diff --git a/emummc/source/FS/offsets/1700_exfat.h b/emummc/source/FS/offsets/1700_exfat.h deleted file mode 100644 index e479724e0..000000000 --- a/emummc/source/FS/offsets/1700_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1700_EXFAT_H__ -#define __FS_1700_EXFAT_H__ - -// Accessor vtable getters -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_GC 0x195B60 -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_SD 0x197830 -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_NAND 0x196030 - -// Hooks -#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_READ 0x191A20 -#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_WRITE 0x191A80 -#define FS_OFFSET_1700_EXFAT_RTLD 0x29D10 -#define FS_OFFSET_1700_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C))) - -#define FS_OFFSET_1700_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B29C0 - -// Misc funcs -#define FS_OFFSET_1700_EXFAT_LOCK_MUTEX 0x18AD00 -#define FS_OFFSET_1700_EXFAT_UNLOCK_MUTEX 0x18AD50 - -#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1919E0 -#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191A00 - -// Misc Data -#define FS_OFFSET_1700_EXFAT_SD_MUTEX 0xFE03F0 -#define FS_OFFSET_1700_EXFAT_NAND_MUTEX 0xFDBB78 -#define FS_OFFSET_1700_EXFAT_ACTIVE_PARTITION 0xFDBBB8 -#define FS_OFFSET_1700_EXFAT_SDMMC_DAS_HANDLE 0xFBC840 - -// NOPs -#define FS_OFFSET_1700_EXFAT_SD_DAS_INIT 0x28C64 - -// Nintendo Paths -#define FS_OFFSET_1700_EXFAT_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068068, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x0007510C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007BEAC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0008F674, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1700_EXFAT_H__ diff --git a/emummc/source/FS/offsets/1800.h b/emummc/source/FS/offsets/1800.h deleted file mode 100644 index 1b0513152..000000000 --- a/emummc/source/FS/offsets/1800.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1800_H__ -#define __FS_1800_H__ - -// Accessor vtable getters -#define FS_OFFSET_1800_SDMMC_ACCESSOR_GC 0x18AB00 -#define FS_OFFSET_1800_SDMMC_ACCESSOR_SD 0x18C800 -#define FS_OFFSET_1800_SDMMC_ACCESSOR_NAND 0x18AFE0 - -// Hooks -#define FS_OFFSET_1800_SDMMC_WRAPPER_READ 0x186A50 -#define FS_OFFSET_1800_SDMMC_WRAPPER_WRITE 0x186AB0 -#define FS_OFFSET_1800_RTLD 0x2A3A4 -#define FS_OFFSET_1800_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) - -#define FS_OFFSET_1800_CLKRST_SET_MIN_V_CLK_RATE 0x1A77D0 - -// Misc funcs -#define FS_OFFSET_1800_LOCK_MUTEX 0x17FCC0 -#define FS_OFFSET_1800_UNLOCK_MUTEX 0x17FD10 - -#define FS_OFFSET_1800_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186A10 -#define FS_OFFSET_1800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186A30 - -// Misc Data -#define FS_OFFSET_1800_SD_MUTEX 0xFD13F0 -#define FS_OFFSET_1800_NAND_MUTEX 0xFCCB28 -#define FS_OFFSET_1800_ACTIVE_PARTITION 0xFCCB68 -#define FS_OFFSET_1800_SDMMC_DAS_HANDLE 0xFB1950 - -// NOPs -#define FS_OFFSET_1800_SD_DAS_INIT 0x28F24 - -// Nintendo Paths -#define FS_OFFSET_1800_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1800_H__ diff --git a/emummc/source/FS/offsets/1800_exfat.h b/emummc/source/FS/offsets/1800_exfat.h deleted file mode 100644 index 358c65f8f..000000000 --- a/emummc/source/FS/offsets/1800_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1800_EXFAT_H__ -#define __FS_1800_EXFAT_H__ - -// Accessor vtable getters -#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_GC 0x195B90 -#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_SD 0x197890 -#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_NAND 0x196070 - -// Hooks -#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_READ 0x191AE0 -#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_WRITE 0x191B40 -#define FS_OFFSET_1800_EXFAT_RTLD 0x2A3A4 -#define FS_OFFSET_1800_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) - -#define FS_OFFSET_1800_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B2860 - -// Misc funcs -#define FS_OFFSET_1800_EXFAT_LOCK_MUTEX 0x18AD50 -#define FS_OFFSET_1800_EXFAT_UNLOCK_MUTEX 0x18ADA0 - -#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191AA0 -#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191AC0 - -// Misc Data -#define FS_OFFSET_1800_EXFAT_SD_MUTEX 0xFE33F0 -#define FS_OFFSET_1800_EXFAT_NAND_MUTEX 0xFDEB28 -#define FS_OFFSET_1800_EXFAT_ACTIVE_PARTITION 0xFDEB68 -#define FS_OFFSET_1800_EXFAT_SDMMC_DAS_HANDLE 0xFBE950 - -// NOPs -#define FS_OFFSET_1800_EXFAT_SD_DAS_INIT 0x28F24 - -// Nintendo Paths -#define FS_OFFSET_1800_EXFAT_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1800_EXFAT_H__ diff --git a/emummc/source/FS/offsets/1810.h b/emummc/source/FS/offsets/1810.h deleted file mode 100644 index 2b71db7a1..000000000 --- a/emummc/source/FS/offsets/1810.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1810_H__ -#define __FS_1810_H__ - -// Accessor vtable getters -#define FS_OFFSET_1810_SDMMC_ACCESSOR_GC 0x18AB00 -#define FS_OFFSET_1810_SDMMC_ACCESSOR_SD 0x18C800 -#define FS_OFFSET_1810_SDMMC_ACCESSOR_NAND 0x18AFE0 - -// Hooks -#define FS_OFFSET_1810_SDMMC_WRAPPER_READ 0x186A50 -#define FS_OFFSET_1810_SDMMC_WRAPPER_WRITE 0x186AB0 -#define FS_OFFSET_1810_RTLD 0x2A3A4 -#define FS_OFFSET_1810_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) - -#define FS_OFFSET_1810_CLKRST_SET_MIN_V_CLK_RATE 0x1A77D0 - -// Misc funcs -#define FS_OFFSET_1810_LOCK_MUTEX 0x17FCC0 -#define FS_OFFSET_1810_UNLOCK_MUTEX 0x17FD10 - -#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186A10 -#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186A30 - -// Misc Data -#define FS_OFFSET_1810_SD_MUTEX 0xFD13F0 -#define FS_OFFSET_1810_NAND_MUTEX 0xFCCB28 -#define FS_OFFSET_1810_ACTIVE_PARTITION 0xFCCB68 -#define FS_OFFSET_1810_SDMMC_DAS_HANDLE 0xFB1950 - -// NOPs -#define FS_OFFSET_1810_SD_DAS_INIT 0x28F24 - -// Nintendo Paths -#define FS_OFFSET_1810_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1810_H__ diff --git a/emummc/source/FS/offsets/1810_exfat.h b/emummc/source/FS/offsets/1810_exfat.h deleted file mode 100644 index 4ac55481c..000000000 --- a/emummc/source/FS/offsets/1810_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_1810_EXFAT_H__ -#define __FS_1810_EXFAT_H__ - -// Accessor vtable getters -#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_GC 0x195B90 -#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_SD 0x197890 -#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_NAND 0x196070 - -// Hooks -#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_READ 0x191AE0 -#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_WRITE 0x191B40 -#define FS_OFFSET_1810_EXFAT_RTLD 0x2A3A4 -#define FS_OFFSET_1810_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) - -#define FS_OFFSET_1810_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B2860 - -// Misc funcs -#define FS_OFFSET_1810_EXFAT_LOCK_MUTEX 0x18AD50 -#define FS_OFFSET_1810_EXFAT_UNLOCK_MUTEX 0x18ADA0 - -#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191AA0 -#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191AC0 - -// Misc Data -#define FS_OFFSET_1810_EXFAT_SD_MUTEX 0xFE33F0 -#define FS_OFFSET_1810_EXFAT_NAND_MUTEX 0xFDEB28 -#define FS_OFFSET_1810_EXFAT_ACTIVE_PARTITION 0xFDEB68 -#define FS_OFFSET_1810_EXFAT_SDMMC_DAS_HANDLE 0xFBE950 - -// NOPs -#define FS_OFFSET_1810_EXFAT_SD_DAS_INIT 0x28F24 - -// Nintendo Paths -#define FS_OFFSET_1810_EXFAT_NINTENDO_PATHS \ -{ \ - {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ -} - -#endif // __FS_1810_EXFAT_H__ diff --git a/emummc/source/FS/offsets/1900.h b/emummc/source/FS/offsets/1900.h deleted file mode 100644 index 82ffd0f94..000000000 --- a/emummc/source/FS/offsets/1900.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2bbf0c899..000000000 --- a/emummc/source/FS/offsets/1900_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 deleted file mode 100644 index b4fe302d7..000000000 --- a/emummc/source/FS/offsets/2000.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 deleted file mode 100644 index a8245a2a7..000000000 --- a/emummc/source/FS/offsets/2000_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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/FS/offsets/2010.h b/emummc/source/FS/offsets/2010.h deleted file mode 100644 index 70691ece7..000000000 --- a/emummc/source/FS/offsets/2010.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_2010_H__ -#define __FS_2010_H__ - -// Accessor vtable getters -#define FS_OFFSET_2010_SDMMC_ACCESSOR_GC 0x1A7DB0 -#define FS_OFFSET_2010_SDMMC_ACCESSOR_SD 0x1AA130 -#define FS_OFFSET_2010_SDMMC_ACCESSOR_NAND 0x1A8560 - -// Hooks -#define FS_OFFSET_2010_SDMMC_WRAPPER_READ 0x1A3C20 -#define FS_OFFSET_2010_SDMMC_WRAPPER_WRITE 0x1A3C80 -#define FS_OFFSET_2010_RTLD 0x2B594 -#define FS_OFFSET_2010_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) - -#define FS_OFFSET_2010_CLKRST_SET_MIN_V_CLK_RATE 0x1C6150 - -// Misc funcs -#define FS_OFFSET_2010_LOCK_MUTEX 0x19CD80 -#define FS_OFFSET_2010_UNLOCK_MUTEX 0x19CDD0 - -#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A3BE0 -#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A3C00 - -// Misc Data -#define FS_OFFSET_2010_SD_MUTEX 0xFF5408 -#define FS_OFFSET_2010_NAND_MUTEX 0xFF0CF0 -#define FS_OFFSET_2010_ACTIVE_PARTITION 0xFF0D30 -#define FS_OFFSET_2010_SDMMC_DAS_HANDLE 0xFD2B08 - -// NOPs -#define FS_OFFSET_2010_SD_DAS_INIT 0x289F4 - -// Nintendo Paths -#define FS_OFFSET_2010_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_2010_H__ diff --git a/emummc/source/FS/offsets/2010_exfat.h b/emummc/source/FS/offsets/2010_exfat.h deleted file mode 100644 index d07c9e6eb..000000000 --- a/emummc/source/FS/offsets/2010_exfat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_2010_EXFAT_H__ -#define __FS_2010_EXFAT_H__ - -// Accessor vtable getters -#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_GC 0x1B36D0 -#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_SD 0x1B5A50 -#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_NAND 0x1B3E80 - -// Hooks -#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_READ 0x1AF540 -#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_WRITE 0x1AF5A0 -#define FS_OFFSET_2010_EXFAT_RTLD 0x2B594 -#define FS_OFFSET_2010_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) - -#define FS_OFFSET_2010_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D1A70 - -// Misc funcs -#define FS_OFFSET_2010_EXFAT_LOCK_MUTEX 0x1A86A0 -#define FS_OFFSET_2010_EXFAT_UNLOCK_MUTEX 0x1A86F0 - -#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500 -#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF520 - -// Misc Data -#define FS_OFFSET_2010_EXFAT_SD_MUTEX 0x1006408 -#define FS_OFFSET_2010_EXFAT_NAND_MUTEX 0x1001CF0 -#define FS_OFFSET_2010_EXFAT_ACTIVE_PARTITION 0x1001D30 -#define FS_OFFSET_2010_EXFAT_SDMMC_DAS_HANDLE 0xFDFB08 - -// NOPs -#define FS_OFFSET_2010_EXFAT_SD_DAS_INIT 0x289F4 - -// Nintendo Paths -#define FS_OFFSET_2010_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_2010_EXFAT_H__ diff --git a/emummc/source/utils/types.h b/emummc/source/utils/types.h index 42bb1fad9..ce4db820c 100644 --- a/emummc/source/utils/types.h +++ b/emummc/source/utils/types.h @@ -18,7 +18,6 @@ #define _TYPES_H_ #include -#include #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -59,6 +58,12 @@ 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 7bffe7dc0..df737a370 100644 --- a/exosphere/loader_stub/loader_stub.mk +++ b/exosphere/loader_stub/loader_stub.mk @@ -15,12 +15,13 @@ ifneq ($(__RECURSIVE__),1) export ATMOSPHERE_TOPDIR := $(CURRENT_DIRECTORY) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR) CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) -BINFILES := +BINFILES := program.lz4 boot_code.lz4 #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -101,7 +102,13 @@ $(OUTPUT).elf : $(OFILES) $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a -secmon_loader_main.o: CXXFLAGS += --embed-dir="$(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR)/" +program.lz4.o: program.lz4 + @echo $(notdir $<) + @$(bin2o) + +boot_code.lz4.o: boot_code.lz4 + @echo $(notdir $<) + @$(bin2o) %.elf: @echo linking $(notdir $@) @@ -110,6 +117,14 @@ secmon_loader_main.o: CXXFLAGS += --embed-dir="$(CURRENT_DIRECTORY)/../program/$ $(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 782d7ac11..368941eb1 100644 --- a/exosphere/loader_stub/source/secmon_loader_main.cpp +++ b/exosphere/loader_stub/source/secmon_loader_main.cpp @@ -15,31 +15,21 @@ */ #include #include "secmon_loader_uncompress.hpp" +#include "program_lz4.h" +#include "boot_code_lz4.h" namespace ams::secmon::loader { - namespace { - - constexpr const u8 SecmonProgramLz4[] = { - #embed - }; - - constexpr const u8 SecmonBootCodeLz4[] = { - #embed - }; - - } - - NORETURN void UncompressAndExecute() { + NORETURN void UncompressAndExecute(const void *program, const void *boot_code) { /* Uncompress the program image. */ - Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), SecmonProgramLz4, sizeof(SecmonProgramLz4)); + Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size); /* Copy the boot image to the end of IRAM */ - u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - sizeof(SecmonBootCodeLz4); - std::memcpy(relocated_boot_code, SecmonBootCodeLz4, sizeof(SecmonBootCodeLz4)); + u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - boot_code_lz4_size; + std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size); /* Uncompress the boot image. */ - Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, sizeof(SecmonBootCodeLz4)); + Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size); /* 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 6640ac2d9..47838e5fa 100644 --- a/exosphere/loader_stub/source/start.s +++ b/exosphere/loader_stub/source/start.s @@ -98,5 +98,8 @@ _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 _ZN3ams6secmon6loader20UncompressAndExecuteEv + b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_ diff --git a/exosphere/program/program.ld b/exosphere/program/program.ld index 2cbd831ef..f0ec57a71 100644 --- a/exosphere/program/program.ld +++ b/exosphere/program/program.ld @@ -106,7 +106,6 @@ 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 5ff3809d0..2be110d84 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 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 +.byte 0x3A, 0x9C, 0xF0, 0x39, 0x70, 0x23, 0xF6, 0xAF, 0x71, 0x44, 0x60, 0xF4, 0x6D, 0xED, 0xA1, 0xD6 /* Mariko Production Master Kek Source. */ -.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A +.byte 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 /* 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. */ @@ -107,10 +107,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x08, 0xE0, 0xF4, 0xBE, 0xAA, 0x6E, 0x5A, 0xC3, 0xA6, 0xBC, 0xFE, 0xB9, 0xE2, 0xA3, 0x24, 0x12 /* Master key 0C encrypted with Master key 0D. */ .byte 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D /* Master key 0D encrypted with Master key 0E. */ .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,10 +125,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x83, 0x67, 0xAF, 0x01, 0xCF, 0x93, 0xA1, 0xAB, 0x80, 0x45, 0xF7, 0x3F, 0x72, 0xFD, 0x3B, 0x38 /* Master key 0C encrypted with Master key 0D. */ .byte 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 /* Master key 0D encrypted with Master key 0E. */ .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. */ @@ -148,10 +140,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x5B, 0x94, 0x63, 0xF7, 0xAD, 0x96, 0x1B, 0xA6, 0x23, 0x30, 0x06, 0x4D, 0x01, 0xE4, 0xCE, 0x1D /* 14.0.0 Device Master Key Source Source. */ .byte 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 /* 15.0.0 Device Master Key Source Source. */ .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. */ @@ -167,10 +155,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xCE, 0x14, 0x74, 0x66, 0x98, 0xA8, 0x6D, 0x7D, 0xBD, 0x54, 0x91, 0x68, 0x5F, 0x1D, 0x0E, 0xEA /* 14.0.0 Device Master Kek Source. */ .byte 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E /* 15.0.0 Device Master Kek Source. */ .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. */ @@ -186,7 +170,3 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x67, 0xD5, 0xD6, 0x0C, 0x08, 0xF5, 0xA3, 0x11, 0xBD, 0x6D, 0x5A, 0xEB, 0x96, 0x24, 0xB0, 0xD2 /* 14.0.0 Device Master Kek Source. */ .byte 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 /* 15.0.0 Device Master Kek Source. */ .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 88c8f1189..e2187ec6a 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 == 20); + static_assert(pkg1::KeyGeneration_Count == 16); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/exosphere/program/source/secmon_user_power_management.cpp b/exosphere/program/source/secmon_user_power_management.cpp index 6f81af026..719dc427a 100644 --- a/exosphere/program/source/secmon_user_power_management.cpp +++ b/exosphere/program/source/secmon_user_power_management.cpp @@ -70,15 +70,6 @@ namespace ams::secmon { } - void PerformUserRebootByPmic() { - /* Ensure that i2c-5 is usable for communicating with the pmic. */ - clkrst::EnableI2c5Clock(); - i2c::Initialize(i2c::Port_5); - - /* Reboot. */ - pmic::ShutdownSystem(true); - } - void PerformUserRebootToRcm() { /* Configure the bootrom to boot to rcm. */ reg::Write(PMC + APBDEV_PMC_SCRATCH0, 0x2); @@ -109,20 +100,11 @@ namespace ams::secmon { } void PerformUserShutDown() { - if (fuse::GetSocType() == fuse::SocType_Mariko) { - /* Ensure that i2c-5 is usable for communicating with the pmic. */ - clkrst::EnableI2c5Clock(); - i2c::Initialize(i2c::Port_5); + /* Load our reboot stub to iram. */ + LoadRebootStub(RebootStubAction_ShutDown); - /* On Mariko shutdown via pmic. */ - pmic::ShutdownSystem(false); - } else /* if (fuse::GetSocType() == fuse::SocType_Erista) */ { - /* Load our reboot stub to iram. */ - LoadRebootStub(RebootStubAction_ShutDown); - - /* Reboot. */ - PerformPmcReboot(); - } + /* Reboot. */ + PerformPmcReboot(); } } diff --git a/exosphere/program/source/secmon_user_power_management.hpp b/exosphere/program/source/secmon_user_power_management.hpp index 678ae3167..ab3e1e6a6 100644 --- a/exosphere/program/source/secmon_user_power_management.hpp +++ b/exosphere/program/source/secmon_user_power_management.hpp @@ -23,13 +23,11 @@ namespace ams::secmon { UserRebootType_ToRcm = 1, UserRebootType_ToPayload = 2, UserRebootType_ToFatalError = 3, - UserRebootType_ByPmic = 4, }; void PerformUserRebootToRcm(); void PerformUserRebootToPayload(); void PerformUserRebootToFatalError(); - void PerformUserRebootByPmic(); void PerformUserShutDown(); } diff --git a/exosphere/program/source/smc/secmon_smc_aes.cpp b/exosphere/program/source/smc/secmon_smc_aes.cpp index 84999fd72..1d5f51ded 100644 --- a/exosphere/program/source/smc/secmon_smc_aes.cpp +++ b/exosphere/program/source/smc/secmon_smc_aes.cpp @@ -161,7 +161,6 @@ namespace ams::secmon::smc { constexpr const u8 EsCommonKeySources[EsCommonKeyType_Count][AesKeySize] = { [EsCommonKeyType_TitleKey] = { 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B }, [EsCommonKeyType_ArchiveKey] = { 0x3B, 0x78, 0xF2, 0x61, 0x0F, 0x9D, 0x5A, 0xE2, 0x7B, 0x4E, 0x45, 0xAF, 0xCB, 0x0B, 0x67, 0x4D }, - [EsCommonKeyType_Unknown2] = { 0x42, 0x64, 0x0B, 0xE3, 0x5F, 0xC6, 0xBE, 0x47, 0xC7, 0xB4, 0x84, 0xC5, 0xEB, 0x63, 0xAA, 0x02 }, }; constexpr const u8 EsSealKeySource[AesKeySize] = { diff --git a/exosphere/program/source/smc/secmon_smc_aes.hpp b/exosphere/program/source/smc/secmon_smc_aes.hpp index ce0d8390f..3a570b09a 100644 --- a/exosphere/program/source/smc/secmon_smc_aes.hpp +++ b/exosphere/program/source/smc/secmon_smc_aes.hpp @@ -22,7 +22,6 @@ namespace ams::secmon::smc { enum EsCommonKeyType { EsCommonKeyType_TitleKey = 0, EsCommonKeyType_ArchiveKey = 1, - EsCommonKeyType_Unknown2 = 2, EsCommonKeyType_Count, }; diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 11f4a693a..365d31f27 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -357,9 +357,6 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; - case UserRebootType_ByPmic: - PerformUserRebootByPmic(); - break; default: return SmcResult::InvalidArgument; } @@ -368,17 +365,18 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; - case UserRebootType_ByPmic: - PerformUserRebootByPmic(); - break; default: return SmcResult::InvalidArgument; } } break; case ConfigItem::ExosphereNeedsShutdown: - if (args.r[3] != 0) { - PerformUserShutDown(); + if (soc_type == fuse::SocType_Erista) { + if (args.r[3] != 0) { + PerformUserShutDown(); + } + } else /* if (soc_type == fuse::SocType_Mariko) */ { + return SmcResult::NotSupported; } break; case ConfigItem::ExospherePayloadAddress: diff --git a/exosphere/program/source/smc/secmon_smc_rsa.cpp b/exosphere/program/source/smc/secmon_smc_rsa.cpp index 920a65bea..34982bb8a 100644 --- a/exosphere/program/source/smc/secmon_smc_rsa.cpp +++ b/exosphere/program/source/smc/secmon_smc_rsa.cpp @@ -32,8 +32,8 @@ namespace ams::secmon::smc { struct PrepareEsDeviceUniqueKeyOption { using KeyGeneration = util::BitPack32::Field<0, 6, int>; - using Type = util::BitPack32::Field<6, 2, EsCommonKeyType>; - using Reserved = util::BitPack32::Field<8, 24, u32>; + using Type = util::BitPack32::Field<6, 1, EsCommonKeyType>; + using Reserved = util::BitPack32::Field<7, 25, u32>; }; constexpr const u8 ModularExponentiateByStorageKeyTable[] = { diff --git a/fusee/loader_stub/source/fusee_loader_uncompress.cpp b/fusee/loader_stub/source/fusee_loader_uncompress.cpp index 94ed4ff73..ace64588f 100644 --- a/fusee/loader_stub/source/fusee_loader_uncompress.cpp +++ b/fusee/loader_stub/source/fusee_loader_uncompress.cpp @@ -96,7 +96,7 @@ namespace ams::nxboot::loader { } void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) { - /* Create and execute a decompressor. */ + /* Create an execute a decompressor. */ Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress(); } diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin deleted file mode 100644 index 821a17342..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin deleted file mode 100644 index 7224626db..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/2.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/2.bin deleted file mode 100644 index d1a915691..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/2.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin deleted file mode 100644 index 5649c6bf6..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin deleted file mode 100644 index ddb817531..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/2.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/2.bin deleted file mode 100644 index 35e1a4b1e..000000000 Binary files a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/2.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin b/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin deleted file mode 100644 index f0de1ed56..000000000 Binary files a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin b/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin deleted file mode 100644 index 99cc3a02e..000000000 Binary files a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin b/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin deleted file mode 100644 index 99cc3a02e..000000000 Binary files a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin deleted file mode 100644 index aeb4ebf67..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin deleted file mode 100644 index 72fb85c13..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin deleted file mode 100644 index ca8213bf4..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin deleted file mode 100644 index fb9189d56..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin deleted file mode 100644 index 4a53db3c3..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin deleted file mode 100644 index 30265925e..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin deleted file mode 100644 index e5a1baa38..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin deleted file mode 100644 index 82255cebe..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin deleted file mode 100644 index 1333e260e..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin deleted file mode 100644 index d1539d555..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin deleted file mode 100644 index f9f325f51..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin deleted file mode 100644 index bf1c6310e..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin deleted file mode 100644 index aeb4ebf67..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin deleted file mode 100644 index a89f97ab0..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin deleted file mode 100644 index 350eb99de..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin deleted file mode 100644 index 1fe6c8925..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin deleted file mode 100644 index bd379aa69..000000000 Binary files a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 index 73e792fb2..0d8bf42d6 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 73dba658a..d8e7c5a10 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 d66625045..3a969c703 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 42e1d924d..e3b2cf75d 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 974d69d9c..9e279a5f5 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 ff84fafe5..0c00bd2d8 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 915757ed9..67a3ddd58 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 35af29230..9514bc894 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 cc856bb57..72671a6c6 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 616e4bef7..a1bf88e91 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 c51e46b47..3b2d9622b 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 486fa90e1..97fe2d33f 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 223760ad7..ee0cb2dd0 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 a022021e0..594bda5fe 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 3ec06a3f4..335d29514 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 cdd389bd6..1b1b28d40 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 34f639ba5..488f98812 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 fdf298bb7..50f00c13a 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 386f938aa..5fe95de28 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 864a18271..8c1df89e8 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 c51e46b47..3b2d9622b 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 486fa90e1..97fe2d33f 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 223760ad7..ee0cb2dd0 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 a022021e0..594bda5fe 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 3ec06a3f4..335d29514 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 cdd389bd6..1b1b28d40 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 34f639ba5..488f98812 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 fdf298bb7..50f00c13a 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 386f938aa..5fe95de28 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 864a18271..8c1df89e8 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 deleted file mode 100644 index b757e62d8..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 deleted file mode 100644 index 4e58de4e3..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 deleted file mode 100644 index a29874bd9..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 index 205fdbb7b..cadd417f1 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 3c6929d62..80af9d717 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 e6c956917..d2768055f 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 f13389e5f..f3a8aca25 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 804393160..6d2f2ef86 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 0fa57ea67..3ab45f9f1 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 deleted file mode 100644 index 205fdbb7b..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 deleted file mode 100644 index 3c6929d62..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 deleted file mode 100644 index 42aa35419..000000000 Binary files a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 and /dev/null differ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 index 3f6041a27..a8fdf10ed 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 b27ed15a4..c5ad29b66 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 f47ee2bf8..3324c9e8f 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 4df1465fa..db56a6486 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 774411526..6cfeb96f4 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 cee1a8a17..9df00662a 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 8188217e0..ffe64ed60 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 1269d9878..768280006 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 8943ef137..185141180 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 c143b846c..f0f784841 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 27f2b519d..ec6b7aea0 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 18423acef..82a720acc 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 5baad7694..9aa35bb1b 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 e6ef1f317..14d7f1b44 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 228a120f8..631e92868 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 718241df0..260bf3d32 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 f24dd27d4..10595c50e 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 e9c0433ab..a97114e27 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 f349fa566..8abd28956 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 8a270c4ab..e758fde99 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 f11e07bcd..3cffc39d9 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 97f963ec6..6d1500d7e 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 986ec2635..dfd43b94a 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 74be6d5d3..29f33852f 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 b757e62d8..53d794d01 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 4e58de4e3..c32abfc77 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 a29874bd9..b97594bc0 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 361da04ad..a9fc86afa 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 cfd755d17..71da3eed0 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 410239cf6..96ff15438 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 f13389e5f..f3a8aca25 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 a92171989..1022eb947 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 c4de070ce..ed395cd54 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 0193ce8cf..f72bb75eb 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 2b1c83884..b3b510aa2 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 e2eec4ee3..d04e69a2e 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 0e027354c..369a4d7b8 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 e490e03f1..92410ca3f 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 a6614cce0..d3ebf31a8 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 5aa1ea39b..846b0fba7 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 2a47d2537..a8de51bea 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 9e22b4421..ac73ca087 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 b0402b601..6a0fa56ac 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 2ff9fd5fd..b7ea6f320 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 f4a26bfac..3081ab081 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 ebc0d3029..0a8217241 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 d3cd2126c..fe9645121 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 7392208b6..12c1e6a19 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 a1aa66a4c..c03d9f26a 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 287d51c75..37e142b08 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 bca7c4e9b..1a7adb41f 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. */ - 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A + 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 + 0x3A, 0x9C, 0xF0, 0x39, 0x70, 0x23, 0xF6, 0xAF, 0x71, 0x44, 0x60, 0xF4, 0x6D, 0xED, 0xA1, 0xD6 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 + 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -70,10 +70,6 @@ namespace ams::nxboot { { 0x5B, 0x94, 0x63, 0xF7, 0xAD, 0x96, 0x1B, 0xA6, 0x23, 0x30, 0x06, 0x4D, 0x01, 0xE4, 0xCE, 0x1D }, /* 14.0.0 Device Master Key Source Source. */ { 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 }, /* 15.0.0 Device Master Key Source Source. */ { 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,10 +86,6 @@ namespace ams::nxboot { { 0x67, 0xD5, 0xD6, 0x0C, 0x08, 0xF5, 0xA3, 0x11, 0xBD, 0x6D, 0x5A, 0xEB, 0x96, 0x24, 0xB0, 0xD2 }, /* 14.0.0 Device Master Kek Source. */ { 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 }, /* 15.0.0 Device Master Kek Source. */ { 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] = { @@ -110,10 +102,6 @@ namespace ams::nxboot { { 0xCE, 0x14, 0x74, 0x66, 0x98, 0xA8, 0x6D, 0x7D, 0xBD, 0x54, 0x91, 0x68, 0x5F, 0x1D, 0x0E, 0xEA }, /* 14.0.0 Device Master Kek Source. */ { 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E }, /* 15.0.0 Device Master Kek Source. */ { 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] = { @@ -133,10 +121,6 @@ namespace ams::nxboot { { 0x83, 0x67, 0xAF, 0x01, 0xCF, 0x93, 0xA1, 0xAB, 0x80, 0x45, 0xF7, 0x3F, 0x72, 0xFD, 0x3B, 0x38 }, /* Master key 0C encrypted with Master key 0D. */ { 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 }, /* Master key 0D encrypted with Master key 0E. */ { 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] = { @@ -156,10 +140,6 @@ namespace ams::nxboot { { 0x08, 0xE0, 0xF4, 0xBE, 0xAA, 0x6E, 0x5A, 0xC3, 0xA6, 0xBC, 0xFE, 0xB9, 0xE2, 0xA3, 0x24, 0x12 }, /* Master key 0C encrypted with Master key 0D. */ { 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D }, /* Master key 0D encrypted with Master key 0E. */ { 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 3a75a043f..f82dc44ef 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 == 20); + static_assert(pkg1::KeyGeneration_Count == 16); 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 000bbe524..4476dd6c6 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -257,14 +257,6 @@ namespace ams::nxboot { return ams::TargetFirmware_15_0_0; } else if (std::memcmp(package1 + 0x10, "20230111", 8) == 0) { return ams::TargetFirmware_16_0_0; - } else if (std::memcmp(package1 + 0x10, "20230906", 8) == 0) { - 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 34e88dfb3..3146b4c8b 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -24,9 +24,6 @@ namespace ams::nxboot { namespace { - constexpr u32 MesoshereMetadataLayout0Magic = util::FourCC<'M','S','S','0'>::Code; - constexpr u32 MesoshereMetadataLayout1Magic = util::FourCC<'M','S','S','1'>::Code; - struct InitialProcessBinaryHeader { static constexpr u32 Magic = util::FourCC<'I','N','I','1'>::Code; @@ -168,24 +165,6 @@ namespace ams::nxboot { FsVersion_16_0_3, FsVersion_16_0_3_Exfat, - FsVersion_17_0_0, - FsVersion_17_0_0_Exfat, - - FsVersion_18_0_0, - FsVersion_18_0_0_Exfat, - - 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_20_1_0, - FsVersion_20_1_0_Exfat, - FsVersion_Count, }; @@ -266,39 +245,10 @@ namespace ams::nxboot { { 0x39, 0xEE, 0x1F, 0x1E, 0x0E, 0xA7, 0x32, 0x5D }, /* FsVersion_16_0_3 */ { 0x62, 0xC6, 0x5E, 0xFD, 0x9A, 0xBF, 0x7C, 0x43 }, /* FsVersion_16_0_3_Exfat */ - - { 0x27, 0x07, 0x3B, 0xF0, 0xA1, 0xB8, 0xCE, 0x61 }, /* FsVersion_17_0_0 */ - { 0xEE, 0x0F, 0x4B, 0xAC, 0x6D, 0x1F, 0xFC, 0x4B }, /* FsVersion_17_0_0_Exfat */ - - { 0x79, 0x5F, 0x5A, 0x5E, 0xB0, 0xC6, 0x77, 0x9E }, /* FsVersion_18_0_0 */ - { 0x1E, 0x2C, 0x64, 0xB1, 0xCC, 0xE2, 0x78, 0x24 }, /* FsVersion_18_0_0_Exfat */ - - { 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 */ - - { 0xED, 0x34, 0xB4, 0x50, 0x58, 0x4A, 0x5B, 0x43 }, /* FsVersion_20_1_0 */ - { 0xA5, 0x1A, 0xA4, 0x92, 0x6C, 0x41, 0x87, 0x59 }, /* FsVersion_20_1_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { - if (target_firmware >= ams::TargetFirmware_17_0_0) { - const u32 *data_32 = reinterpret_cast(data); - const u32 branch_target = (data_32[0] & 0x00FFFFFF); - for (size_t i = branch_target; i < branch_target + 0x1000 / sizeof(u32); ++i) { - const u32 ini_offset = (i * sizeof(u32)) + data_32[i]; - if (data_32[i + 1] == 0 && ini_offset <= header->meta.payload_sizes[0] && std::memcmp(data + ini_offset, "INI1", 4) == 0) { - return reinterpret_cast(data + ini_offset); - } - } - - return nullptr; - } else if (target_firmware >= ams::TargetFirmware_8_0_0) { + if (target_firmware >= ams::TargetFirmware_8_0_0) { /* Try to find initial process binary. */ const u32 *data_32 = reinterpret_cast(data); for (size_t i = 0; i < 0x1000 / sizeof(u32); ++i) { @@ -415,6 +365,15 @@ namespace ams::nxboot { return nullptr; } + InitialProcessMeta *FindInitialProcess(const se::Sha256Hash &hash) { + for (InitialProcessMeta *cur = std::addressof(g_initial_process_meta); cur != nullptr; cur = cur->next) { + if (std::memcmp(std::addressof(cur->kip_hash), std::addressof(hash), sizeof(hash)) == 0) { + return cur; + } + } + return nullptr; + } + u32 GetPatchSegments(const InitialProcessHeader *kip, u32 offset, size_t size) { /* Create segment mask. */ u32 segments = 0; @@ -495,6 +454,78 @@ namespace ams::nxboot { meta->patches_tail = new_patch; } + void AddIps24PatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { + while (size > 0) { + /* Read offset, stopping at EOF */ + const u32 offset = (static_cast(ips[0]) << 16) | (static_cast(ips[1]) << 8) | (static_cast(ips[2]) << 0); + if (offset == 0x454F46) { + break; + } + + /* Read size. */ + const u16 cur_size = (static_cast(ips[3]) << 8) | (static_cast(ips[4]) << 0); + + if (cur_size > 0) { + /* Add patch. */ + AddPatch(meta, offset, ips + 5, cur_size, false); + + /* Advance. */ + ips += (5 + cur_size); + size -= (5 + cur_size); + } else { + /* Read RLE size */ + const u16 rle_size = (static_cast(ips[5]) << 8) | (static_cast(ips[6]) << 0); + + /* Add patch. */ + AddPatch(meta, offset, ips + 7, rle_size, true); + + /* Advance. */ + ips += 8; + size -= 8; + } + } + } + + void AddIps32PatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { + while (size > 0) { + /* Read offset, stopping at EOF */ + const u32 offset = (static_cast(ips[0]) << 24) | (static_cast(ips[1]) << 16) | (static_cast(ips[2]) << 8) | (static_cast(ips[3]) << 0); + if (offset == 0x45454F46) { + break; + } + + /* Read size. */ + const u16 cur_size = (static_cast(ips[4]) << 8) | (static_cast(ips[5]) << 0); + + if (cur_size > 0) { + /* Add patch. */ + AddPatch(meta, offset, ips + 6, cur_size, false); + + /* Advance. */ + ips += (6 + cur_size); + size -= (6 + cur_size); + } else { + /* Read RLE size */ + const u16 rle_size = (static_cast(ips[6]) << 8) | (static_cast(ips[7]) << 0); + + /* Add patch. */ + AddPatch(meta, offset, ips + 8, rle_size, true); + + /* Advance. */ + ips += 9; + size -= 9; + } + } + } + + void AddIpsPatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { + if (std::memcmp(ips, "PATCH", 5) == 0) { + AddIps24PatchToKip(meta, ips + 5, size - 5); + } else if (std::memcmp(ips, "IPS32", 5) == 0) { + AddIps32PatchToKip(meta, ips + 5, size - 5); + } + } + constexpr const u8 NogcPatch0[] = { 0x80 }; @@ -639,52 +670,6 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x191409, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x16B9A0, NogcPatch1, sizeof(NogcPatch1)); break; - case FsVersion_17_0_0: - AddPatch(fs_meta, 0x18B149, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x165200, NogcPatch1, sizeof(NogcPatch1)); - break; - case FsVersion_17_0_0_Exfat: - AddPatch(fs_meta, 0x195FA9, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x170060, NogcPatch1, sizeof(NogcPatch1)); - break; - case FsVersion_18_0_0: - AddPatch(fs_meta, 0x18AF49, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x164B50, NogcPatch1, sizeof(NogcPatch1)); - break; - case FsVersion_18_0_0_Exfat: - AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); - break; - case FsVersion_18_1_0: - AddPatch(fs_meta, 0x18AF49, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x164B50, NogcPatch1, sizeof(NogcPatch1)); - break; - case FsVersion_18_1_0_Exfat: - 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: - case FsVersion_20_1_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: - case FsVersion_20_1_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; } @@ -878,6 +863,106 @@ namespace ams::nxboot { } /* TODO ams.tma2: add mount_host patches. */ + + /* Add generic patches. */ + { + /* Create patch path. */ + char patch_path[0x220]; + std::memcpy(patch_path, "sdmc:/atmosphere/kip_patches", 0x1D); + + fs::DirectoryHandle patch_root_dir; + if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(patch_root_dir), patch_path))) { + ON_SCOPE_EXIT { fs::CloseDirectory(patch_root_dir); }; + + s64 count; + fs::DirectoryEntry entries[1]; + while (R_SUCCEEDED(fs::ReadDirectory(std::addressof(count), entries, patch_root_dir, util::size(entries))) && count > 0) { + /* Check that dir is a dir. */ + if (fs::GetEntryType(entries[0]) != fs::DirectoryEntryType_Directory) { + continue; + } + + /* For compatibility, ignore the old "default_nogc" patches. */ + if (std::strcmp(entries[0].file_name, "default_nogc") == 0) { + continue; + } + + /* Get filename length. */ + const int dir_len = std::strlen(entries[0].file_name); + + /* Adjust patch path. */ + patch_path[0x1C] = '/'; + std::memcpy(patch_path + 0x1D, entries[0].file_name, dir_len + 1); + + /* Try to open the patch subdirectory. */ + fs::DirectoryHandle patch_dir; + if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(patch_dir), patch_path))) { + ON_SCOPE_EXIT { fs::CloseDirectory(patch_dir); }; + + /* Read patches. */ + while (R_SUCCEEDED(fs::ReadDirectory(std::addressof(count), entries, patch_dir, util::size(entries))) && count > 0) { + /* Check that file is a file. */ + if (fs::GetEntryType(entries[0]) != fs::DirectoryEntryType_File) { + continue; + } + + /* Get filename length. */ + const int name_len = std::strlen(entries[0].file_name); + + /* Adjust patch path. */ + patch_path[0x1D + dir_len] = '/'; + std::memcpy(patch_path + 0x1D + dir_len + 1, entries[0].file_name, name_len + 1); + + /* Check that file is "{hex}.ips" file. */ + const int path_len = 0x1D + dir_len + 1 + name_len; + if (name_len != 0x44 || std::memcmp(patch_path + path_len - 4, ".ips", 5) != 0) { + continue; + } + + /* Check that the filename is hex. */ + bool valid_name = true; + se::Sha256Hash patch_name = {}; + u32 shift = 4; + for (int i = 0; i < name_len - 4; ++i) { + const char c = entries[0].file_name[i]; + + u8 val; + if ('0' <= c && c <= '9') { + val = (c - '0'); + } else if ('a' <= c && c <= 'f') { + val = (c - 'a') + 10; + } else if ('A' <= c && c <= 'F') { + val = (c - 'A') + 10; + } else { + valid_name = false; + break; + } + + patch_name.bytes[i >> 1] |= val << shift; + shift ^= 4; + } + + /* Ignore invalid patches. */ + if (!valid_name) { + continue; + } + + /* Find kip for the patch. */ + auto *kip_meta = FindInitialProcess(patch_name); + if (kip_meta == nullptr) { + continue; + } + + /* Read the ips patch. */ + s64 file_size; + if (u8 *ips = static_cast(ReadFile(std::addressof(file_size), patch_path)); ips != nullptr) { + AddIpsPatchToKip(kip_meta, ips, static_cast(file_size)); + } + } + } + } + } + } } /* Return the fs version we're using. */ @@ -926,20 +1011,7 @@ namespace ams::nxboot { } /* Set the embedded ini pointer. */ - const u32 magic = *reinterpret_cast(payload_data + 4); - if (magic == MesoshereMetadataLayout0Magic) { - std::memcpy(payload_data + 8, std::addressof(meso_size), sizeof(meso_size)); - } else if (magic == MesoshereMetadataLayout1Magic) { - if (const u32 meta_offset = *reinterpret_cast(payload_data + 8); meta_offset <= meso_size - sizeof(meso_size)) { - s64 relative_offset = meso_size - meta_offset; - std::memcpy(payload_data + meta_offset, std::addressof(relative_offset), sizeof(relative_offset)); - } else { - ShowFatalError("Invalid mesosphere metadata layout!\n"); - } - } else { - ShowFatalError("Unknown mesosphere metadata version!\n"); - } - + std::memcpy(payload_data + 8, std::addressof(meso_size), sizeof(meso_size)); /* Get the ini pointer. */ InitialProcessBinaryHeader * const ini = reinterpret_cast(payload_data + meso_size); diff --git a/fusee/program/source/mtc/fusee_mtc.cpp b/fusee/program/source/mtc/fusee_mtc.cpp index 7b513c9e3..74a1acd7b 100644 --- a/fusee/program/source/mtc/fusee_mtc.cpp +++ b/fusee/program/source/mtc/fusee_mtc.cpp @@ -60,12 +60,6 @@ namespace ams::nxboot { /* DramId_MarikoHoagMicron1y4gb */ 0x0F, /* DramId_MarikoAulaMicron1y4gb */ 0x0F, /* DramId_MarikoAulaSamsung1y8gbX */ 0x0D, - /* DramId_MarikoIowaHynix1a4gb */ 0x13, - /* DramId_MarikoHoagHynix1a4gb */ 0x13, - /* DramId_MarikoAulaHynix1a4gb */ 0x13, - /* DramId_MarikoIowaMicron1a4gb */ 0x14, - /* DramId_MarikoHoagMicron1a4gb */ 0x14, - /* DramId_MarikoAulaMicron1a4gb */ 0x14, }; int GetMemoryTrainingTableIndex() { diff --git a/fusee/program/source/mtc/fusee_mtc_mariko.cpp b/fusee/program/source/mtc/fusee_mtc_mariko.cpp index e6497af70..b231229af 100644 --- a/fusee/program/source/mtc/fusee_mtc_mariko.cpp +++ b/fusee/program/source/mtc/fusee_mtc_mariko.cpp @@ -97,8 +97,6 @@ namespace ams::nxboot { HANDLE_CASE(0x10, T210b01SdevEmcDvfsTableH1y4gb01) HANDLE_CASE(0x11, T210b01SdevEmcDvfsTableS1y8gb04) HANDLE_CASE(0x12, T210b01SdevEmcDvfsTableS1z4gb01) - HANDLE_CASE(0x13, T210b01SdevEmcDvfsTableH1a4gb01) - HANDLE_CASE(0x14, T210b01SdevEmcDvfsTableM1a4gb01) default: ShowFatalError("Unknown EmcDvfsTimingTableIndex: %d\n", index); } 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 9e36044f7..56f8574ca 100644 --- a/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc +++ b/fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc @@ -421,7 +421,6 @@ 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 6fc664d4d..5d3296c59 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_erista.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_erista.inc @@ -14,15 +14,2784 @@ * along with this program. If not, see . */ -constexpr const u8 T210SdevEmcDvfsTableS6gb01[] = { - #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin" +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 T210SdevEmcDvfsTableH4gb01[] = { - #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/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 T210SdevEmcDvfsTableS4gb01[] = { - #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/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, }; diff --git a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc index de7f89dfb..11ed68d5a 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc @@ -14,71 +14,1616 @@ * along with this program. If not, see . */ -constexpr const u8 T210b01SdevEmcDvfsTableM4gb03[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin" +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 T210b01SdevEmcDvfsTableS4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/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 T210b01SdevEmcDvfsTableS1z4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/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 T210b01SdevEmcDvfsTableS1y8gbY01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/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 T210b01SdevEmcDvfsTableM1a4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/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 T210b01SdevEmcDvfsTableH4gb03[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/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 T210b01SdevEmcDvfsTableS1y4gbX03[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/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 T210b01SdevEmcDvfsTableM1y4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/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 T210b01SdevEmcDvfsTableS1y4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/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 T210b01SdevEmcDvfsTableH1y4gb01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/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 T210b01SdevEmcDvfsTableS4gb03[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/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 T210b01SdevEmcDvfsTableS4gbY01[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/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 T210b01SdevEmcDvfsTableS1y8gb04[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/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 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[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin" -}; - -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[] = { - #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/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, }; diff --git a/fusee/program/source/sdram/fusee_sdram.cpp b/fusee/program/source/sdram/fusee_sdram.cpp index 1ad265a14..46133beee 100644 --- a/fusee/program/source/sdram/fusee_sdram.cpp +++ b/fusee/program/source/sdram/fusee_sdram.cpp @@ -1002,16 +1002,14 @@ namespace ams::nxboot { \ constexpr u32 SrcLow = RANGE_LOW(SRC_RANGE); \ constexpr u32 DstLow = RANGE_LOW(DST_RANGE); \ - constexpr auto Shift = (SrcLow < DstLow) ? (DstLow - SrcLow) \ - : (SrcLow - DstLow); \ \ cur_reg_value &= ~Mask; \ if constexpr (SrcLow == DstLow) { \ cur_reg_value |= (src_value & Mask); \ } else if constexpr (SrcLow < DstLow) { \ - cur_reg_value |= ((src_value << Shift) & Mask); \ + cur_reg_value |= ((src_value << (DstLow - SrcLow)) & Mask); \ } else { \ - cur_reg_value |= ((src_value >> Shift) & Mask); \ + cur_reg_value |= ((src_value >> (SrcLow - DstLow)) & Mask); \ } \ } \ } diff --git a/fusee/program/source/sdram/fusee_sdram_params.inc b/fusee/program/source/sdram/fusee_sdram_params.inc index a89dcd2ca..133e42b9f 100644 --- a/fusee/program/source/sdram/fusee_sdram_params.inc +++ b/fusee/program/source/sdram/fusee_sdram_params.inc @@ -14,8 +14,68 @@ * along with this program. If not, see . */ -constexpr inline const u8 SdramParamsErista0_1[0x3CB] = { - #embed "../../sdram_params/lz/sdram_params_erista_0_1.lz4" +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 * const SdramParamsErista0 = SdramParamsErista0_1; @@ -24,8 +84,68 @@ 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[0x3C7] = { - #embed "../../sdram_params/lz/sdram_params_erista_2_3.lz4" +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 * const SdramParamsErista2 = SdramParamsErista2_3; @@ -34,8 +154,73 @@ 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[0x418] = { - #embed "../../sdram_params/lz/sdram_params_erista_4_5.lz4" +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 * const SdramParamsErista4 = SdramParamsErista4_5; @@ -44,8 +229,67 @@ 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[0x3BD] = { - #embed "../../sdram_params/lz/sdram_params_erista_6_7.lz4" +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 * const SdramParamsErista6 = SdramParamsErista6_7; @@ -54,8 +298,70 @@ 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[0x3EE] = { - #embed "../../sdram_params/lz/sdram_params_mariko_0_1.lz4" +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 * const SdramParamsMariko0 = SdramParamsMariko0_1; @@ -64,8 +370,76 @@ 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[0x449] = { - #embed "../../sdram_params/lz/sdram_params_mariko_2_3.lz4" +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 * const SdramParamsMariko2 = SdramParamsMariko2_3; @@ -74,8 +448,71 @@ 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[0x3F7] = { - #embed "../../sdram_params/lz/sdram_params_mariko_4_5.lz4" +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 * const SdramParamsMariko4 = SdramParamsMariko4_5; @@ -84,8 +521,74 @@ 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[0x427] = { - #embed "../../sdram_params/lz/sdram_params_mariko_6_7.lz4" +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 * const SdramParamsMariko6 = SdramParamsMariko6_7; @@ -94,8 +597,74 @@ 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[0x428] = { - #embed "../../sdram_params/lz/sdram_params_mariko_8_9.lz4" +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 * const SdramParamsMariko8 = SdramParamsMariko8_9; @@ -104,8 +673,68 @@ 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[0x3D2] = { - #embed "../../sdram_params/lz/sdram_params_mariko_10_11.lz4" +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 * const SdramParamsMariko10 = SdramParamsMariko10_11; @@ -114,8 +743,67 @@ 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[0x3C2] = { - #embed "../../sdram_params/lz/sdram_params_mariko_12_13.lz4" +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 * const SdramParamsMariko12 = SdramParamsMariko12_13; diff --git a/fusee/program/update_mtc_tables.py b/fusee/program/update_mtc_tables.py index a6f73b07c..7a7e0edd1 100644 --- a/fusee/program/update_mtc_tables.py +++ b/fusee/program/update_mtc_tables.py @@ -57,22 +57,6 @@ 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 837ad7351..453720406 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,9 +177,6 @@ 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, TargetFirmware_13_2_1, diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp index a44c92218..63e245659 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp @@ -116,9 +116,7 @@ namespace ams::kern::arch::arm { u32 ipriorityr[NumLocalInterrupts / 4]; u32 itargetsr[NumLocalInterrupts / 4]; u32 icfgr[NumLocalInterrupts / 16]; - u32 spendsgir[4]; }; - static_assert(sizeof(LocalState{}.spendsgir) == sizeof(GicDistributor{}.spendsgir)); struct GlobalState { u32 isenabler[NumGlobalInterrupts / 32]; diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp index b8e3a9565..94206bfae 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp @@ -19,8 +19,13 @@ namespace ams::kern::init { struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments { + u64 ttbr0; + u64 ttbr1; + u64 tcr; + u64 mair; u64 cpuactlr; u64 cpuectlr; + u64 sctlr; u64 sp; u64 entrypoint; u64 argument; @@ -28,8 +33,13 @@ namespace ams::kern::init { static_assert(alignof(KInitArguments) == util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)); static_assert(sizeof(KInitArguments) == std::max(INIT_ARGUMENTS_SIZE, util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE))); + static_assert(AMS_OFFSETOF(KInitArguments, ttbr0) == INIT_ARGUMENTS_TTBR0); + static_assert(AMS_OFFSETOF(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1); + static_assert(AMS_OFFSETOF(KInitArguments, tcr) == INIT_ARGUMENTS_TCR); + static_assert(AMS_OFFSETOF(KInitArguments, mair) == INIT_ARGUMENTS_MAIR); static_assert(AMS_OFFSETOF(KInitArguments, cpuactlr) == INIT_ARGUMENTS_CPUACTLR); static_assert(AMS_OFFSETOF(KInitArguments, cpuectlr) == INIT_ARGUMENTS_CPUECTLR); + static_assert(AMS_OFFSETOF(KInitArguments, sctlr) == INIT_ARGUMENTS_SCTLR); static_assert(AMS_OFFSETOF(KInitArguments, sp) == INIT_ARGUMENTS_SP); static_assert(AMS_OFFSETOF(KInitArguments, entrypoint) == INIT_ARGUMENTS_ENTRYPOINT); static_assert(AMS_OFFSETOF(KInitArguments, argument) == INIT_ARGUMENTS_ARGUMENT); 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 b653da7bd..f47407c89 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 @@ -87,8 +87,9 @@ namespace ams::kern::arch::arm64::init { template static ALWAYS_INLINE KPhysicalAddress AllocateNewPageTable(PageAllocator &allocator, u64 phys_to_virt_offset) { - MESOSPHERE_UNUSED(phys_to_virt_offset); - return allocator.Allocate(PageSize); + auto address = allocator.Allocate(PageSize); + ClearNewPageTable(address, phys_to_virt_offset); + return address; } static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address, u64 phys_to_virt_offset) { @@ -110,47 +111,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->IsMappedBlock() || l1_entry->IsMappedEmpty()) { + if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { 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->IsMappedBlock() && block_size == L1BlockSize) { + if (l1_entry->IsBlock() && block_size == L1BlockSize) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { - const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; + if (l2_entry->IsBlock() || l2_entry->IsEmpty()) { + const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l2_entry->IsMappedBlock() && block_size == advance_size) { + if (l2_entry->IsBlock() && block_size == advance_size) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty()); - const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l3_entry->IsMappedBlock() && block_size == advance_size) { + if (l3_entry->IsBlock() && block_size == advance_size) { count++; } } @@ -164,10 +165,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->IsMappedBlock() || l1_entry->IsMappedEmpty()) { + if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { 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->IsMappedBlock() && block_size == L1BlockSize) { + if (l1_entry->IsBlock() && block_size == L1BlockSize) { if ((count++) == index) { return virt_addr; } @@ -177,16 +178,16 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { - const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; + if (l2_entry->IsBlock() || l2_entry->IsEmpty()) { + const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l2_entry->IsMappedBlock() && block_size == advance_size) { + if (l2_entry->IsBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -196,18 +197,18 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty()); - const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l3_entry->IsMappedBlock() && block_size == advance_size) { + if (l3_entry->IsBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -220,29 +221,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->IsMappedBlock()) { + if (l1_entry->IsBlock()) { MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize); return l1_entry; } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock()) { + if (l2_entry->IsBlock()) { const size_t real_size = (l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size); return l2_entry; } - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); const size_t real_size = (l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size); @@ -340,7 +341,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->IsMappedTable()) { + if (!l1_entry->IsTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -371,7 +372,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->IsMappedTable()) { + if (!l2_entry->IsTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -416,12 +417,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->IsMappedBlock()) { + if (l1_entry->IsBlock()) { /* Unmap the L1 entry, if we should. */ if (ShouldUnmap(l1_entry)) { *static_cast(l1_entry) = InvalidPageTableEntry; } - } else if (l1_entry->IsMappedTable()) { + } else if (l1_entry->IsTable()) { /* Get the L2 table. */ L2PageTableEntry * const l2_table = reinterpret_cast(GetInteger(l1_entry->GetTable()) + phys_to_virt_offset); @@ -430,7 +431,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->IsMappedBlock()) { + if (l2_entry->IsBlock()) { const size_t num_to_clear = (l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize) / L2BlockSize; if (ShouldUnmap(l2_entry)) { @@ -442,7 +443,7 @@ namespace ams::kern::arch::arm64::init { } l2_index = l2_index + num_to_clear - 1; - } else if (l2_entry->IsMappedTable()) { + } else if (l2_entry->IsTable()) { /* Get the L3 table. */ L3PageTableEntry * const l3_table = reinterpret_cast(GetInteger(l2_entry->GetTable()) + phys_to_virt_offset); @@ -450,7 +451,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->IsMappedBlock()) { + if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsBlock()) { const size_t num_to_clear = (l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize) / L3BlockSize; if (ShouldUnmap(l3_entry)) { @@ -498,25 +499,25 @@ namespace ams::kern::arch::arm64::init { /* Get the L1 entry. */ const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); - if (l1_entry->IsMappedBlock()) { + if (l1_entry->IsBlock()) { return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); /* Get the L2 entry. */ const L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock()) { + if (l2_entry->IsBlock()) { return l2_entry->GetBlock() + (GetInteger(virt_addr) & (L2BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* Get the L3 entry. */ const L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); return l3_entry->GetBlock() + (GetInteger(virt_addr) & (L3BlockSize - 1)); } @@ -561,26 +562,26 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped, update. */ - if (l1_entry->IsMappedBlock()) { + if (l1_entry->IsBlock()) { UpdateExtents(l1_entry->GetBlock(), L1BlockSize); continue; } /* Not a block, so we must have a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock()) { + if (l2_entry->IsBlock()) { 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->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* We must have a mapped l3 entry to inspect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); UpdateExtents(l3_entry->GetBlock(), l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize); } @@ -602,11 +603,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->IsMappedBlock()) { + if (l1_entry->IsBlock()) { return false; } - if (!l1_entry->IsMappedTable()) { + if (!l1_entry->IsTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L1BlockSize, L1BlockSize); continue; @@ -615,11 +616,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->IsMappedBlock()) { + if (l2_entry->IsBlock()) { return false; } - if (!l2_entry->IsMappedTable()) { + if (!l2_entry->IsTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L2BlockSize, L2BlockSize); continue; @@ -628,7 +629,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->IsMappedBlock()) { + if (l3_entry->IsBlock()) { return false; } @@ -648,7 +649,7 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* Check if an L1 block is present. */ - if (l1_entry->IsMappedBlock()) { + if (l1_entry->IsBlock()) { /* 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 +670,10 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock()) { + if (l2_entry->IsBlock()) { const KPhysicalAddress block = l2_entry->GetBlock(); if (l2_entry->IsContiguous()) { @@ -720,11 +721,11 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); /* We must have a mapped l3 entry to reprotect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); const KPhysicalAddress block = l3_entry->GetBlock(); if (l3_entry->IsContiguous()) { @@ -882,12 +883,6 @@ namespace ams::kern::arch::arm64::init { const size_t ind_max = ((aligned_end - aligned_start) / align) - 1; while (true) { if (const uintptr_t random_address = aligned_start + (KSystemControl::Init::GenerateRandomRange(0, ind_max) * align); this->TryAllocate(random_address, size)) { - /* Clear the allocated pages. */ - volatile u64 *ptr = reinterpret_cast(random_address); - for (size_t i = 0; i < size / sizeof(u64); ++i) { - ptr[i] = 0; - } - return random_address; } } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h index 8dfafdc7b..97b50afb6 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h @@ -94,8 +94,3 @@ label_done: ENABLE_FPU(xtmp1) \ GET_THREAD_CONTEXT_AND_RESTORE_FPCR_FPSR(ctx, xtmp1, xtmp2, wtmp1, wtmp2) \ RESTORE_FPU32_ALL_REGISTERS(ctx, xtmp1) - -#define ERET_WITH_SPECULATION_BARRIER \ - eret; \ - dsb nsh; \ - isb diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h index 46d956e61..b585f44eb 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h @@ -246,12 +246,17 @@ #define THREAD_LOCAL_REGION_SIZE 0x200 /* ams::kern::init::KInitArguments, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp */ -#define INIT_ARGUMENTS_SIZE 0x28 -#define INIT_ARGUMENTS_CPUACTLR 0x00 -#define INIT_ARGUMENTS_CPUECTLR 0x08 -#define INIT_ARGUMENTS_SP 0x10 -#define INIT_ARGUMENTS_ENTRYPOINT 0x18 -#define INIT_ARGUMENTS_ARGUMENT 0x20 +#define INIT_ARGUMENTS_SIZE 0x50 +#define INIT_ARGUMENTS_TTBR0 0x00 +#define INIT_ARGUMENTS_TTBR1 0x08 +#define INIT_ARGUMENTS_TCR 0x10 +#define INIT_ARGUMENTS_MAIR 0x18 +#define INIT_ARGUMENTS_CPUACTLR 0x20 +#define INIT_ARGUMENTS_CPUECTLR 0x28 +#define INIT_ARGUMENTS_SCTLR 0x30 +#define INIT_ARGUMENTS_SP 0x38 +#define INIT_ARGUMENTS_ENTRYPOINT 0x40 +#define INIT_ARGUMENTS_ARGUMENT 0x48 /* ams::kern::KScheduler (::SchedulingState), https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp */ /* NOTE: Due to constraints on ldarb relative offsets, KSCHEDULER_NEEDS_SCHEDULING cannot trivially be changed, and will require assembly edits. */ diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index 61e066fee..3889b264f 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -372,10 +372,6 @@ namespace ams::kern::arch::arm64::cpu { this->SetBit(19, en); return *this; } - - constexpr ALWAYS_INLINE bool GetWxn() const { - return this->GetBits(19, 1) != 0; - } }; /* Accessors for timer registers. */ 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 7bc1a96f1..f6f27c019 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,13 +93,9 @@ 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); @@ -109,9 +105,6 @@ 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); @@ -125,24 +118,22 @@ namespace ams::kern::arch::arm64 { /* Set page attribute. */ if (properties.io) { MESOSPHERE_ABORT_UNLESS(!properties.uncached); - MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); entry.SetPageAttribute(PageTableEntry::PageAttribute_Device_nGnRnE) .SetUserExecuteNever(true); } else if (properties.uncached) { - MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); - entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable) - .SetUserExecuteNever(true); + entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable); } else { entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemory); + } - 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 user execute never bit. */ + if (properties.perm != KMemoryPermission_UserReadExecute) { + MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); + entry.SetUserExecuteNever(true); } /* Set AP[1] based on perm. */ @@ -177,47 +168,53 @@ namespace ams::kern::arch::arm64 { return entry; } public: - constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_asid() { /* ... */ } + constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ } explicit KPageTable() { /* ... */ } static NOINLINE void Initialize(s32 core_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); + ALWAYS_INLINE void Activate(u32 proc_id) { + cpu::SwitchProcess(m_ttbr, 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, size_t process_index); + NOINLINE Result InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); Result Finalize(); - - static void NoteUpdatedCallback(const void *pt) { - /* Note the update. */ - static_cast(pt)->NoteUpdated(); - } 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); + 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); + 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 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); + Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, 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, PageLinkedList *page_list, bool reuse_ll); - bool MergePages(TraversalContext *context, PageLinkedList *page_list); - void MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list); + bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); - 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); + 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 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); @@ -227,6 +224,7 @@ 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 ed32262f9..93925e3fa 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,22 +20,18 @@ 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 = BlocksPerContiguousBlock * L1BlockSize; + constexpr size_t L1ContiguousBlockSize = 0x10 * L1BlockSize; constexpr size_t L2BlockSize = 2_MB; - constexpr size_t L2ContiguousBlockSize = BlocksPerContiguousBlock * L2BlockSize; + constexpr size_t L2ContiguousBlockSize = 0x10 * L2BlockSize; constexpr size_t L3BlockSize = PageSize; - constexpr size_t L3ContiguousBlockSize = BlocksPerContiguousBlock * L3BlockSize; + constexpr size_t L3ContiguousBlockSize = 0x10 * L3BlockSize; class PageTableEntry { public: struct InvalidTag{}; struct TableTag{}; struct BlockTag{}; - struct SeparateContiguousTag{}; enum Permission : u64 { Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)), @@ -122,26 +118,7 @@ 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(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)) + : m_attributes(static_cast(perm) | static_cast(AccessFlag_Accessed) | static_cast(p_a) | static_cast(share) | static_cast(ExtensionFlag_Valid) | static_cast(m)) { /* ... */ } @@ -188,24 +165,14 @@ 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; } @@ -219,16 +186,8 @@ 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 = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); return m_attributes & BaseMask; } @@ -237,45 +196,10 @@ namespace ams::kern::arch::arm64 { return (m_attributes & BaseMaskForMerge) == attr; } - 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; @@ -305,7 +229,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) | 0x1) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) { /* ... */ } @@ -367,7 +291,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) | 0x1) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) { /* ... */ } @@ -432,13 +356,12 @@ 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) | 0x3) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | static_cast(ExtensionFlag_TestTableMask)) { /* ... */ } 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 b1a97fca0..bdf461a0c 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 @@ -30,27 +30,17 @@ namespace ams::kern::arch::arm64 { KPhysicalAddress phys_addr; size_t block_size; u8 sw_reserved_bits; - u8 attr; constexpr bool IsHeadMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHead) != 0; } constexpr bool IsHeadAndBodyMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadAndBody) != 0; } constexpr bool IsTailMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadTail) != 0; } }; - 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; + const L1PageTableEntry *l1_entry; + const L2PageTableEntry *l2_entry; + const L3PageTableEntry *l3_entry; }; - - using EntryUpdatedCallback = void (*)(const void *); private: static constexpr size_t PageBits = util::CountTrailingZeros(PageSize); static constexpr size_t NumLevels = 3; @@ -62,19 +52,11 @@ 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 - static constexpr ALWAYS_INLINE u64 SelectBits(u64 value) { + 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)); } @@ -87,14 +69,13 @@ 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); } - public: - static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); } + + 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; private: L1PageTableEntry *m_table; bool m_is_kernel; @@ -123,17 +104,11 @@ 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(); @@ -145,17 +120,6 @@ 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 e18a6fbc8..0d074a6b2 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(size_t process_index, u64 id) { + void Activate(u64 id) { /* Activate the page table with the specified contextidr. */ - m_page_table.ActivateProcess(process_index, id); + m_page_table.Activate(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, size_t process_index) { - R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index)); + Result Initialize(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, 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(id, as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, system_resource, resource_limit)); } void Finalize() { m_page_table.Finalize(); } @@ -110,12 +110,12 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.MapRegion(region_type, perm)); } - Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size) { - R_RETURN(m_page_table.MapInsecurePhysicalMemory(address, size)); + Result MapInsecureMemory(KProcessAddress address, size_t size) { + R_RETURN(m_page_table.MapInsecureMemory(address, size)); } - Result UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size) { - R_RETURN(m_page_table.UnmapInsecurePhysicalMemory(address, size)); + Result UnmapInsecureMemory(KProcessAddress address, size_t size) { + R_RETURN(m_page_table.UnmapInsecureMemory(address, size)); } Result MapPageGroup(KProcessAddress addr, const KPageGroup &pg, KMemoryState state, KMemoryPermission perm) { @@ -150,24 +150,20 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.InvalidateProcessDataCache(address, size)); } - Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size) { - 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) { - R_RETURN(m_page_table.ReadDebugIoMemory(buffer, address, size, state)); + Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size) { + R_RETURN(m_page_table.ReadDebugIoMemory(buffer, address, size)); } Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size) { R_RETURN(m_page_table.WriteDebugMemory(address, buffer, size)); } - Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state) { - R_RETURN(m_page_table.WriteDebugIoMemory(address, buffer, size, state)); + Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size) { + R_RETURN(m_page_table.WriteDebugIoMemory(address, buffer, size)); } Result LockForMapDeviceAddressSpace(bool *out_is_io, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned, bool check_heap) { @@ -300,7 +296,6 @@ namespace ams::kern::arch::arm64 { bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { return m_page_table.IsInUnsafeAliasRegion(addr, size); } bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return m_page_table.CanContain(addr, size, state); } - bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { return m_page_table.CanContain(addr, size, state); } KProcessAddress GetAddressSpaceStart() const { return m_page_table.GetAddressSpaceStart(); } KProcessAddress GetHeapRegionStart() const { return m_page_table.GetHeapRegionStart(); } @@ -316,8 +311,6 @@ namespace ams::kern::arch::arm64 { size_t GetKernelMapRegionSize() const { return m_page_table.GetKernelMapRegionSize(); } size_t GetAliasCodeRegionSize() const { return m_page_table.GetAliasCodeRegionSize(); } - size_t GetAliasRegionExtraSize() const { return m_page_table.GetAliasRegionExtraSize(); } - size_t GetNormalMemorySize() const { return m_page_table.GetNormalMemorySize(); } size_t GetCodeSize() const { return m_page_table.GetCodeSize(); } 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 0c0602289..c8ccca33d 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 @@ -23,13 +23,15 @@ namespace ams::kern::arch::arm64 { class KSupervisorPageTable { private: KPageTable m_page_table; + u64 m_ttbr0_identity[cpu::NumCores]; public: - constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize) { /* ... */ } + constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize), m_ttbr0_identity() { /* ... */ } NOINLINE void Initialize(s32 core_id); void Activate() { - m_page_table.ActivateKernel(); + /* Activate, using process id = 0xFFFFFFFF */ + m_page_table.Activate(0xFFFFFFFF); } void ActivateForInit() { @@ -59,6 +61,8 @@ namespace ams::kern::arch::arm64 { return m_page_table.GetPhysicalAddress(out, address); } + constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return m_ttbr0_identity[core_id]; } + void DumpMemoryBlocks() const { return m_page_table.DumpMemoryBlocks(); } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp index a3e8f080b..76ec13937 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp @@ -16,10 +16,11 @@ #pragma once #include #include +#include namespace ams::kern::arch::arm64::smc { - template + template void SecureMonitorCall(u64 *buf) { /* Load arguments into registers. */ register u64 x0 asm("x0") = buf[0]; @@ -31,18 +32,34 @@ namespace ams::kern::arch::arm64::smc { register u64 x6 asm("x6") = buf[6]; register u64 x7 asm("x7") = buf[7]; - /* Backup the current thread pointer. */ - const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); - /* Perform the call. */ - __asm__ __volatile__("smc %c[smc_id]" - : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) - : [smc_id]"i"(SmcId) - : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" - ); + if constexpr (DisableInterrupt) { + KScopedInterruptDisable di; - /* Restore the current thread pointer into X18. */ - cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); + /* Backup the current thread pointer. */ + const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); + + __asm__ __volatile__("smc %c[smc_id]" + : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) + : [smc_id]"i"(SmcId) + : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" + ); + + /* Restore the current thread pointer into X18. */ + cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); + } else { + /* Backup the current thread pointer. */ + const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); + + __asm__ __volatile__("smc %c[smc_id]" + : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) + : [smc_id]"i"(SmcId) + : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" + ); + + /* Restore the current thread pointer into X18. */ + cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); + } /* Store arguments to output. */ buf[0] = x0; @@ -61,18 +78,18 @@ namespace ams::kern::arch::arm64::smc { PsciFunction_CpuOn = 0xC4000003, }; - template + template u64 PsciCall(PsciFunction function, u64 x1 = 0, u64 x2 = 0, u64 x3 = 0, u64 x4 = 0, u64 x5 = 0, u64 x6 = 0, u64 x7 = 0) { ams::svc::lp64::SecureMonitorArguments args = { { function, x1, x2, x3, x4, x5, x6, x7 } }; - SecureMonitorCall(args.r); + SecureMonitorCall(args.r); return args.r[0]; } - template + template u64 CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { - return PsciCall(PsciFunction_CpuOn, core_id, entrypoint, arg); + return PsciCall(PsciFunction_CpuOn, core_id, entrypoint, arg); } } 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 17c6c6a44..202be5f51 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,140 +21,38 @@ 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) { - return Impl::CopyMemoryFromUser(dst, src, size); - } + 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 CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) { - return Impl::CopyMemoryFromUserAligned32Bit(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 CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) { - return Impl::CopyMemoryFromUserAligned64Bit(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 CopyMemoryFromUserSize64Bit(void *dst, const void *src) { - return Impl::CopyMemoryFromUserSize64Bit(dst, src); - } + 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 CopyMemoryFromUserSize32Bit(void *dst, const void *src) { - return Impl::CopyMemoryFromUserSize32Bit(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 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); - } + 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); }; 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 4e82780b0..b12e8d02e 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,8 +24,4 @@ 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 8e1829849..a0cfce5a1 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,7 +45,6 @@ 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/init/kern_init_elf64.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp index 76d858426..6b507f74c 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp @@ -114,23 +114,6 @@ namespace ams::kern::init::Elf::Elf64 { } }; - class Relr { - private: - Xword m_info; - public: - constexpr ALWAYS_INLINE bool IsLocation() const { - return (m_info & 1) == 0; - } - - constexpr ALWAYS_INLINE Xword GetLocation() const { - return m_info; - } - - constexpr ALWAYS_INLINE Xword GetBitmap() const { - return m_info >> 1; - } - }; - enum DynamicTag { DT_NULL = 0, DT_RELA = 7, @@ -138,10 +121,6 @@ namespace ams::kern::init::Elf::Elf64 { DT_REL = 17, DT_RELENT = 19, - DT_RELRSZ = 35, - DT_RELR = 36, - DT_RELRENT = 37, - DT_RELACOUNT = 0x6ffffff9, DT_RELCOUNT = 0x6ffffffa }; diff --git a/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp index db952edf4..daf0e81a4 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp @@ -31,22 +31,8 @@ namespace ams::kern::init { u32 dynamic_offset; u32 init_array_offset; u32 init_array_end_offset; - u32 sysreg_offset; }; static_assert(util::is_pod::value); - static_assert(sizeof(KernelLayout) == 0x34); - - #if defined(ATMOSPHERE_ARCH_ARM64) - struct KernelSystemRegisters { - u64 ttbr0_el1; - u64 ttbr1_el1; - u64 tcr_el1; - u64 mair_el1; - u64 sctlr_el1; - }; - #else - struct KernelSystemRegisters { - }; - #endif + static_assert(sizeof(KernelLayout) == 0x30); } \ No newline at end of file diff --git a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp index a7dfeab71..2ab3b6090 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp @@ -32,17 +32,10 @@ namespace ams::kern { struct InitialProcessBinaryLayout { uintptr_t address; uintptr_t _08; - uintptr_t kern_address; - }; - - struct InitialProcessBinaryLayoutWithSize { - InitialProcessBinaryLayout layout; - size_t size; }; KPhysicalAddress GetInitialProcessBinaryPhysicalAddress(); - size_t GetInitialProcessBinarySize(); - void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size); + void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr); u64 GetInitialProcessIdMin(); u64 GetInitialProcessIdMax(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp index f4ef74e6b..4066de80d 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp @@ -39,16 +39,14 @@ namespace ams::kern { } } - Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s64 value, s64 timeout) { + Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s32 value, s64 timeout) { switch (type) { case ams::svc::ArbitrationType_WaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, static_cast(value), false, timeout)); + R_RETURN(this->WaitIfLessThan(addr, value, false, timeout)); case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, static_cast(value), true, timeout)); + R_RETURN(this->WaitIfLessThan(addr, value, true, timeout)); case ams::svc::ArbitrationType_WaitIfEqual: - R_RETURN(this->WaitIfEqual(addr, static_cast(value), timeout)); - case ams::svc::ArbitrationType_WaitIfEqual64: - R_RETURN(this->WaitIfEqual64(addr, value, timeout)); + R_RETURN(this->WaitIfEqual(addr, value, timeout)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } @@ -58,7 +56,6 @@ 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 775c0054c..9e20dd254 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(ams::svc::CreateProcessFlag flags, Type type, size_t code_size); - static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type); + static uintptr_t GetAddressSpaceStart(size_t width, Type type); + static size_t GetAddressSpaceSize(size_t width, Type type); static void SetAddressSpaceSize(size_t width, Type type, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp index dc99f5ceb..1b7b433b8 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp @@ -358,7 +358,7 @@ namespace ams::kern { void Detach() { /* Close our object, if we have one. */ if (T * const object = m_object; AMS_LIKELY(object != nullptr)) { - /* Set our object to a debug sentinel value, which will cause a crash if accessed. */ + /* Set our object to a debug sentinel value, which will cause crash if accessed. */ m_object = reinterpret_cast(1); /* Close reference to our object. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index 2c74b835c..7b5a93dcc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -168,10 +168,9 @@ namespace ams::kern { struct DebugFlags { using IdBits = Field<0, CapabilityId + 1>; - DEFINE_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_FIELD(ForceDebugProd, AllowDebug, 1, bool); - DEFINE_FIELD(ForceDebug, ForceDebugProd, 1, bool); - DEFINE_FIELD(Reserved, ForceDebug, 12); + DEFINE_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_FIELD(ForceDebug, AllowDebug, 1, bool); + DEFINE_FIELD(Reserved, ForceDebug, 13); }; #undef DEFINE_FIELD @@ -193,7 +192,7 @@ namespace ams::kern { u32 m_program_type; private: constexpr bool SetSvcAllowed(u32 id) { - if (AMS_LIKELY(id < static_cast(m_svc_access_flags.GetCount()))) { + if (AMS_LIKELY(id < m_svc_access_flags.GetCount())) { m_svc_access_flags[id] = true; return true; } else { @@ -202,7 +201,7 @@ namespace ams::kern { } constexpr bool SetInterruptPermitted(u32 id) { - if (AMS_LIKELY(id < static_cast(m_irq_access_flags.GetCount()))) { + if (AMS_LIKELY(id < m_irq_access_flags.GetCount())) { m_irq_access_flags[id] = true; return true; } else { @@ -256,10 +255,6 @@ 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 6978b9152..6c8fe54f7 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -32,7 +32,6 @@ 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: @@ -63,10 +62,6 @@ 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_initial_process_reader.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp index 8d22c3b73..8ee175e96 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp @@ -133,7 +133,7 @@ namespace ams::kern { } Result MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const; - void Load(const KPageGroup &pg, KVirtualAddress data) const; + Result Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms, KProcessAddress src) const; Result SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter ¶ms) const; }; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index 57876fbcb..faed32239 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -44,7 +44,6 @@ namespace ams::kern { KMemoryState_FlagCanChangeAttribute = (1 << 24), KMemoryState_FlagCanCodeMemory = (1 << 25), KMemoryState_FlagLinearMapped = (1 << 26), - KMemoryState_FlagCanPermissionLock = (1 << 27), KMemoryState_FlagsData = KMemoryState_FlagCanReprotect | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonDeviceIpc | KMemoryState_FlagCanUseNonSecureIpc | @@ -67,22 +66,18 @@ namespace ams::kern { KMemoryState_Free = ams::svc::MemoryState_Free, - - KMemoryState_IoMemory = ams::svc::MemoryState_Io | KMemoryState_FlagMapped | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, - KMemoryState_IoRegister = ams::svc::MemoryState_Io | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, - - - KMemoryState_Static = ams::svc::MemoryState_Static | KMemoryState_FlagCanQueryPhysical, + KMemoryState_Io = ams::svc::MemoryState_Io | KMemoryState_FlagMapped | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, + KMemoryState_Static = ams::svc::MemoryState_Static | KMemoryState_FlagMapped | KMemoryState_FlagCanQueryPhysical, KMemoryState_Code = ams::svc::MemoryState_Code | KMemoryState_FlagsCode | KMemoryState_FlagCanMapProcess, - KMemoryState_CodeData = ams::svc::MemoryState_CodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeMemory | KMemoryState_FlagCanPermissionLock, + KMemoryState_CodeData = ams::svc::MemoryState_CodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeMemory, KMemoryState_Normal = ams::svc::MemoryState_Normal | KMemoryState_FlagsData | KMemoryState_FlagCanCodeMemory, KMemoryState_Shared = ams::svc::MemoryState_Shared | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped, /* KMemoryState_Alias was removed after 1.0.0. */ KMemoryState_AliasCode = ams::svc::MemoryState_AliasCode | KMemoryState_FlagsCode | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias, - KMemoryState_AliasCodeData = ams::svc::MemoryState_AliasCodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias | KMemoryState_FlagCanCodeMemory - | KMemoryState_FlagCanPermissionLock, + KMemoryState_AliasCodeData = ams::svc::MemoryState_AliasCodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias | KMemoryState_FlagCanCodeMemory, + KMemoryState_Ipc = ams::svc::MemoryState_Ipc | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, @@ -90,7 +85,7 @@ namespace ams::kern { KMemoryState_Stack = ams::svc::MemoryState_Stack | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, - KMemoryState_ThreadLocal = ams::svc::MemoryState_ThreadLocal | KMemoryState_FlagLinearMapped, + KMemoryState_ThreadLocal = ams::svc::MemoryState_ThreadLocal | KMemoryState_FlagMapped | KMemoryState_FlagLinearMapped, KMemoryState_Transfered = ams::svc::MemoryState_Transfered | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanChangeAttribute | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, @@ -109,44 +104,43 @@ namespace ams::kern { KMemoryState_NonDeviceIpc = ams::svc::MemoryState_NonDeviceIpc | KMemoryState_FlagsMisc | KMemoryState_FlagCanUseNonDeviceIpc, - KMemoryState_Kernel = ams::svc::MemoryState_Kernel, + KMemoryState_Kernel = ams::svc::MemoryState_Kernel | KMemoryState_FlagMapped, KMemoryState_GeneratedCode = ams::svc::MemoryState_GeneratedCode | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagCanDebug | KMemoryState_FlagLinearMapped, KMemoryState_CodeOut = ams::svc::MemoryState_CodeOut | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped, KMemoryState_Coverage = ams::svc::MemoryState_Coverage | KMemoryState_FlagMapped, - KMemoryState_Insecure = ams::svc::MemoryState_Insecure | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped | KMemoryState_FlagCanChangeAttribute - | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanQueryPhysical + KMemoryState_Insecure = ams::svc::MemoryState_Insecure | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped | KMemoryState_FlagCanChangeAttribute + | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, }; #if 1 static_assert(KMemoryState_Free == 0x00000000); - static_assert(KMemoryState_IoMemory == 0x00182001); - static_assert(KMemoryState_IoRegister == 0x00180001); - static_assert(KMemoryState_Static == 0x00040002); + static_assert(KMemoryState_Io == 0x00182001); + static_assert(KMemoryState_Static == 0x00042002); static_assert(KMemoryState_Code == 0x04DC7E03); - static_assert(KMemoryState_CodeData == 0x0FFEBD04); + static_assert(KMemoryState_CodeData == 0x07FEBD04); static_assert(KMemoryState_Normal == 0x077EBD05); static_assert(KMemoryState_Shared == 0x04402006); static_assert(KMemoryState_AliasCode == 0x04DD7E08); - static_assert(KMemoryState_AliasCodeData == 0x0FFFBD09); + static_assert(KMemoryState_AliasCodeData == 0x07FFBD09); static_assert(KMemoryState_Ipc == 0x045C3C0A); static_assert(KMemoryState_Stack == 0x045C3C0B); - static_assert(KMemoryState_ThreadLocal == 0x0400000C); + static_assert(KMemoryState_ThreadLocal == 0x0400200C); static_assert(KMemoryState_Transfered == 0x055C3C0D); static_assert(KMemoryState_SharedTransfered == 0x045C380E); static_assert(KMemoryState_SharedCode == 0x0440380F); static_assert(KMemoryState_Inaccessible == 0x00000010); static_assert(KMemoryState_NonSecureIpc == 0x045C3811); static_assert(KMemoryState_NonDeviceIpc == 0x044C2812); - static_assert(KMemoryState_Kernel == 0x00000013); + static_assert(KMemoryState_Kernel == 0x00002013); static_assert(KMemoryState_GeneratedCode == 0x04402214); static_assert(KMemoryState_CodeOut == 0x04402015); - static_assert(KMemoryState_Coverage == 0x00002016); /* TODO: Is this correct? */ - static_assert(KMemoryState_Insecure == 0x055C3817); + static_assert(KMemoryState_Coverage == 0x00002016); + static_assert(KMemoryState_Insecure == 0x05583817); #endif enum KMemoryPermission : u8 { @@ -177,21 +171,20 @@ namespace ams::kern { }; constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) { - return static_cast((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & ams::svc::MemoryPermission_Write) ? KMemoryPermission_KernelWrite : KMemoryPermission_None) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None)); + return static_cast((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None)); } enum KMemoryAttribute : u8 { - KMemoryAttribute_None = 0x00, - KMemoryAttribute_All = 0xFF, - KMemoryAttribute_UserMask = KMemoryAttribute_All, + KMemoryAttribute_None = 0x00, + KMemoryAttribute_All = 0xFF, + KMemoryAttribute_UserMask = KMemoryAttribute_All, - KMemoryAttribute_Locked = ams::svc::MemoryAttribute_Locked, - KMemoryAttribute_IpcLocked = ams::svc::MemoryAttribute_IpcLocked, - KMemoryAttribute_DeviceShared = ams::svc::MemoryAttribute_DeviceShared, - KMemoryAttribute_Uncached = ams::svc::MemoryAttribute_Uncached, - KMemoryAttribute_PermissionLocked = ams::svc::MemoryAttribute_PermissionLocked, + KMemoryAttribute_Locked = ams::svc::MemoryAttribute_Locked, + KMemoryAttribute_IpcLocked = ams::svc::MemoryAttribute_IpcLocked, + KMemoryAttribute_DeviceShared = ams::svc::MemoryAttribute_DeviceShared, + KMemoryAttribute_Uncached = ams::svc::MemoryAttribute_Uncached, - KMemoryAttribute_SetMask = KMemoryAttribute_Uncached | KMemoryAttribute_PermissionLocked, + KMemoryAttribute_SetMask = KMemoryAttribute_Uncached, }; enum KMemoryBlockDisableMergeAttribute : u8 { @@ -200,8 +193,7 @@ namespace ams::kern { KMemoryBlockDisableMergeAttribute_DeviceLeft = (1u << 1), KMemoryBlockDisableMergeAttribute_IpcLeft = (1u << 2), KMemoryBlockDisableMergeAttribute_Locked = (1u << 3), - /* ... */ - KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 5), + KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 4), KMemoryBlockDisableMergeAttribute_AllLeft = KMemoryBlockDisableMergeAttribute_Normal | KMemoryBlockDisableMergeAttribute_DeviceLeft | KMemoryBlockDisableMergeAttribute_IpcLeft | KMemoryBlockDisableMergeAttribute_Locked, KMemoryBlockDisableMergeAttribute_AllRight = KMemoryBlockDisableMergeAttribute_DeviceRight, @@ -266,10 +258,6 @@ namespace ams::kern { return m_state; } - constexpr ams::svc::MemoryState GetSvcState() const { - return static_cast(m_state & KMemoryState_Mask); - } - constexpr KMemoryPermission GetPermission() const { return m_permission; } @@ -289,18 +277,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()) { @@ -332,10 +320,6 @@ namespace ams::kern { return this->GetEndAddress() - 1; } - constexpr KMemoryState GetState() const { - return m_memory_state; - } - constexpr u16 GetIpcLockCount() const { return m_ipc_lock_count; } @@ -344,10 +328,6 @@ 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; } @@ -379,15 +359,16 @@ namespace ams::kern { public: explicit KMemoryBlock() { /* ... */ } - 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 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 void Initialize(KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { + constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { MESOSPHERE_ASSERT_THIS(); m_device_disable_merge_left_count = 0; m_device_disable_merge_right_count = 0; @@ -458,14 +439,6 @@ namespace ams::kern { } } - constexpr void UpdateAttribute(u32 mask, u32 attr) { - MESOSPHERE_ASSERT_THIS(); - MESOSPHERE_ASSERT((mask & KMemoryAttribute_IpcLocked) == 0); - MESOSPHERE_ASSERT((mask & KMemoryAttribute_DeviceShared) == 0); - - m_attribute = static_cast((m_attribute & ~mask) | attr); - } - constexpr void Split(KMemoryBlock *block, KProcessAddress addr) { MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT(this->GetAddress() < addr); 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 f2888ec65..99caae0c2 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp @@ -99,15 +99,12 @@ 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); void UpdateLock(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, MemoryBlockLockFunction lock_func, KMemoryPermission perm); - void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); - - void UpdateAttribute(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, u32 mask, u32 attr); + void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr); iterator FindIterator(KProcessAddress address) const { return m_memory_block_tree.find(KMemoryBlock(util::ConstantInitialize, address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None)); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index 99ef1f6b5..ca23119bc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -164,7 +164,6 @@ 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()]; @@ -186,21 +185,21 @@ namespace ams::kern { } } - Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index); + Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random); 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_min_heap_indexes() + : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process() { /* ... */ } - NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts); + NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size); NOINLINE Result InitializeOptimizedMemory(u64 process_id, Pool pool); NOINLINE void FinalizeOptimizedMemory(u64 process_id, Pool pool); NOINLINE KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); - NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_pages, u32 option); + NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option); NOINLINE Result AllocateForProcess(KPageGroup *out, size_t num_pages, u32 option, u64 process_id, u8 fill_pattern); Pool GetPool(KPhysicalAddress address) const { @@ -300,10 +299,6 @@ 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_memory_region_type.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp index f90908bf4..7023c34e6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp @@ -212,9 +212,7 @@ namespace ams::kern { static_assert(KMemoryRegionType_DramKernelInitPt.GetValue() == (0x44E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); constexpr inline const auto KMemoryRegionType_DramKernelSecureAppletMemory = KMemoryRegionType_DramKernelBase.DeriveSparse(1, 3, 0).SetAttribute(KMemoryRegionAttr_LinearMapped); - constexpr inline const auto KMemoryRegionType_DramKernelSecureUnknown = KMemoryRegionType_DramKernelBase.DeriveSparse(1, 3, 1).SetAttribute(KMemoryRegionAttr_LinearMapped); static_assert(KMemoryRegionType_DramKernelSecureAppletMemory.GetValue() == (0x18E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); - static_assert(KMemoryRegionType_DramKernelSecureUnknown.GetValue() == (0x28E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); constexpr inline const auto KMemoryRegionType_DramReservedEarly = KMemoryRegionType_DramReservedBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); static_assert(KMemoryRegionType_DramReservedEarly.GetValue() == (0x16 | KMemoryRegionAttr_NoUserMap)); @@ -230,55 +228,53 @@ namespace ams::kern { constexpr inline const auto KMemoryRegionType_DramPoolPartition = KMemoryRegionType_DramHeapBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); static_assert(KMemoryRegionType_DramPoolPartition.GetValue() == (0x26 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - constexpr inline const auto KMemoryRegionType_DramPoolManagement = KMemoryRegionType_DramPoolPartition.Derive(4, 0).SetAttribute(KMemoryRegionAttr_CarveoutProtected); - /* UNUSED: .Derive(4, 1); */ - /* UNUSED: .Derive(4, 2); */ - constexpr inline const auto KMemoryRegionType_DramUserPool = KMemoryRegionType_DramPoolPartition.Derive(4, 3); - static_assert(KMemoryRegionType_DramPoolManagement.GetValue() == (0xE6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); - static_assert(KMemoryRegionType_DramUserPool .GetValue() == (0x266 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + constexpr inline const auto KMemoryRegionType_DramPoolManagement = KMemoryRegionType_DramPoolPartition.DeriveTransition(0, 2).DeriveTransition().SetAttribute(KMemoryRegionAttr_CarveoutProtected); + constexpr inline const auto KMemoryRegionType_DramUserPool = KMemoryRegionType_DramPoolPartition.DeriveTransition(1, 2).DeriveTransition(); + static_assert(KMemoryRegionType_DramPoolManagement.GetValue() == (0x166 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); + static_assert(KMemoryRegionType_DramUserPool.GetValue() == (0x1A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); constexpr inline const auto KMemoryRegionType_DramApplicationPool = KMemoryRegionType_DramUserPool.Derive(4, 0); constexpr inline const auto KMemoryRegionType_DramAppletPool = KMemoryRegionType_DramUserPool.Derive(4, 1); constexpr inline const auto KMemoryRegionType_DramSystemNonSecurePool = KMemoryRegionType_DramUserPool.Derive(4, 2); constexpr inline const auto KMemoryRegionType_DramSystemPool = KMemoryRegionType_DramUserPool.Derive(4, 3).SetAttribute(KMemoryRegionAttr_CarveoutProtected); - static_assert(KMemoryRegionType_DramApplicationPool .GetValue() == (0xE66 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramAppletPool .GetValue() == (0x1666 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() == (0x1A66 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramSystemPool .GetValue() == (0x2666 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); + static_assert(KMemoryRegionType_DramApplicationPool .GetValue() == (0x7A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramAppletPool .GetValue() == (0xBA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() == (0xDA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramSystemPool .GetValue() == (0x13A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); - constexpr inline const auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 4, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelPtHeap = KMemoryRegionType_Dram.DeriveSparse(1, 4, 1); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelTraceBuffer = KMemoryRegionType_Dram.DeriveSparse(1, 4, 2); + constexpr inline const auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 3, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelPtHeap = KMemoryRegionType_Dram.DeriveSparse(1, 3, 1); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelTraceBuffer = KMemoryRegionType_Dram.DeriveSparse(1, 3, 2); static_assert(KMemoryRegionType_VirtualDramHeapBase .GetValue() == 0x1A); static_assert(KMemoryRegionType_VirtualDramKernelPtHeap .GetValue() == 0x2A); static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A); /* UNUSED: .DeriveSparse(2, 2, 0); */ - constexpr inline const auto KMemoryRegionType_VirtualDramUnknownDebug = KMemoryRegionType_Dram.Advance(2).Derive(4, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureAppletMemory = KMemoryRegionType_Dram.Advance(2).Derive(4, 1); - /* UNUSED: .Derive(4, 2); */ - constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureUnknown = KMemoryRegionType_Dram.Advance(2).Derive(4, 3); - static_assert(KMemoryRegionType_VirtualDramUnknownDebug .GetValue() == (0x32)); - static_assert(KMemoryRegionType_VirtualDramKernelSecureAppletMemory.GetValue() == (0x52)); - static_assert(KMemoryRegionType_VirtualDramKernelSecureUnknown .GetValue() == (0x92)); + constexpr inline const auto KMemoryRegionType_VirtualDramUnknownDebug = KMemoryRegionType_Dram.DeriveSparse(2, 2, 1); + static_assert(KMemoryRegionType_VirtualDramUnknownDebug.GetValue() == (0x52)); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureAppletMemory = KMemoryRegionType_Dram.DeriveSparse(3, 1, 0); + static_assert(KMemoryRegionType_VirtualDramKernelSecureAppletMemory.GetValue() == (0x62)); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 1); - constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 2); - /* UNUSED: .Derive(4, 3); */ - static_assert(KMemoryRegionType_VirtualDramKernelInitPt .GetValue() == 0x31A); - static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x51A); - static_assert(KMemoryRegionType_VirtualDramUserPool .GetValue() == 0x61A); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1); + constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2); + static_assert(KMemoryRegionType_VirtualDramKernelInitPt .GetValue() == 0x19A); + static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x29A); + static_assert(KMemoryRegionType_VirtualDramUserPool .GetValue() == 0x31A); - constexpr inline const auto KMemoryRegionType_VirtualDramApplicationPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramAppletPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 1); - constexpr inline const auto KMemoryRegionType_VirtualDramSystemNonSecurePool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 2); - constexpr inline const auto KMemoryRegionType_VirtualDramSystemPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 3); - static_assert(KMemoryRegionType_VirtualDramApplicationPool .GetValue() == 0x361A); - static_assert(KMemoryRegionType_VirtualDramAppletPool .GetValue() == 0x561A); - static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x661A); - static_assert(KMemoryRegionType_VirtualDramSystemPool .GetValue() == 0x961A); + /* NOTE: For unknown reason, the pools are derived out-of-order here. */ + /* It's worth eventually trying to understand why Nintendo made this choice. */ + /* UNUSED: .Derive(6, 0); */ + /* UNUSED: .Derive(6, 1); */ + constexpr inline const auto KMemoryRegionType_VirtualDramAppletPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 2); + constexpr inline const auto KMemoryRegionType_VirtualDramApplicationPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 3); + constexpr inline const auto KMemoryRegionType_VirtualDramSystemNonSecurePool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 4); + constexpr inline const auto KMemoryRegionType_VirtualDramSystemPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 5); + static_assert(KMemoryRegionType_VirtualDramAppletPool .GetValue() == 0x1B1A); + static_assert(KMemoryRegionType_VirtualDramApplicationPool .GetValue() == 0x271A); + static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x2B1A); + static_assert(KMemoryRegionType_VirtualDramSystemPool .GetValue() == 0x331A); constexpr inline const auto KMemoryRegionType_ArchDeviceBase = KMemoryRegionType_Kernel.DeriveTransition(0, 1).SetSparseOnly(); constexpr inline const auto KMemoryRegionType_BoardDeviceBase = KMemoryRegionType_Kernel.DeriveTransition(0, 2).SetDenseOnly(); @@ -332,14 +328,12 @@ namespace ams::kern { static_assert(KMemoryRegionType_KernelTemp.GetValue() == 0x31); constexpr ALWAYS_INLINE KMemoryRegionType GetTypeForVirtualLinearMapping(u32 type_id) { - if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { + if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) { + return KMemoryRegionType_VirtualDramKernelTraceBuffer; + } else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { return KMemoryRegionType_VirtualDramKernelPtHeap; } else if (KMemoryRegionType_DramKernelSecureAppletMemory.IsAncestorOf(type_id)) { return KMemoryRegionType_VirtualDramKernelSecureAppletMemory; - } else if (KMemoryRegionType_DramKernelSecureUnknown.IsAncestorOf(type_id)) { - return KMemoryRegionType_VirtualDramKernelSecureUnknown; - } else if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) { - return KMemoryRegionType_VirtualDramKernelTraceBuffer; } else if ((type_id | KMemoryRegionAttr_ShouldKernelMap) == type_id) { return KMemoryRegionType_VirtualDramUnknownDebug; } else { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp index 2ab0a4670..9beef7f1c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp @@ -145,8 +145,6 @@ namespace ams::kern { bool IsEquivalentTo(const KPageGroup &rhs) const; - Result CopyRangeTo(KPageGroup &out, size_t offset, size_t size) const; - ALWAYS_INLINE bool operator==(const KPageGroup &rhs) const { return this->IsEquivalentTo(rhs); } @@ -160,16 +158,8 @@ namespace ams::kern { private: const KPageGroup *m_pg; public: - explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup *gp, bool not_first = true) : m_pg(gp) { - if (m_pg) { - if (not_first) { - m_pg->Open(); - } else { - m_pg->OpenFirst(); - } - } - } - explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup &gp, bool not_first = true) : KScopedPageGroup(std::addressof(gp), not_first) { /* ... */ } + explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup *gp) : m_pg(gp) { if (m_pg) { m_pg->Open(); } } + explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup &gp) : KScopedPageGroup(std::addressof(gp)) { /* ... */ } ALWAYS_INLINE ~KScopedPageGroup() { if (m_pg) { m_pg->Close(); } } ALWAYS_INLINE void CancelClose() { 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 7b2c722e1..06d735504 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -62,21 +62,18 @@ namespace ams::kern { KPhysicalAddress m_address; size_t m_size; bool m_heap; - u8 m_attr; public: - constexpr MemoryRange() : m_address(Null), m_size(0), m_heap(false), m_attr(0) { /* ... */ } + constexpr MemoryRange() : m_address(Null), m_size(0), m_heap(false) { /* ... */ } - void Set(KPhysicalAddress address, size_t size, bool heap, u8 attr) { + void Set(KPhysicalAddress address, size_t size, bool heap) { m_address = address; m_size = size; m_heap = heap; - m_attr = attr; } constexpr KPhysicalAddress GetAddress() const { return m_address; } constexpr size_t GetSize() const { return m_size; } constexpr bool IsHeap() const { return m_heap; } - constexpr u8 GetAttribute() const { return m_attr; } void Open(); void Close(); @@ -89,19 +86,10 @@ namespace ams::kern { MemoryFillValue_Heap = 'Z', }; - enum RegionType { - RegionType_KernelMap = 0, - RegionType_Stack = 1, - RegionType_Alias = 2, - RegionType_Heap = 3, - - RegionType_Count, - }; - enum OperationType { OperationType_Map = 0, - OperationType_MapGroup = 1, - OperationType_MapFirstGroup = 2, + OperationType_MapFirst = 1, + OperationType_MapGroup = 2, OperationType_Unmap = 3, OperationType_ChangePermissions = 4, OperationType_ChangePermissionsAndRefresh = 5, @@ -177,9 +165,15 @@ namespace ams::kern { private: KProcessAddress m_address_space_start; KProcessAddress m_address_space_end; - KProcessAddress m_region_starts[RegionType_Count]; - KProcessAddress m_region_ends[RegionType_Count]; + KProcessAddress m_heap_region_start; + KProcessAddress m_heap_region_end; KProcessAddress m_current_heap_end; + KProcessAddress m_alias_region_start; + KProcessAddress m_alias_region_end; + KProcessAddress m_stack_region_start; + KProcessAddress m_stack_region_end; + KProcessAddress m_kernel_map_region_start; + KProcessAddress m_kernel_map_region_end; KProcessAddress m_alias_code_region_start; KProcessAddress m_alias_code_region_end; KProcessAddress m_code_region_start; @@ -189,7 +183,6 @@ namespace ams::kern { size_t m_mapped_unsafe_physical_memory; size_t m_mapped_insecure_memory; size_t m_mapped_ipc_server_memory; - size_t m_alias_region_extra_size; mutable KLightLock m_general_lock; mutable KLightLock m_map_physical_memory_lock; KLightLock m_device_map_lock; @@ -210,12 +203,12 @@ namespace ams::kern { MemoryFillValue m_stack_fill_value; public: constexpr explicit KPageTableBase(util::ConstantInitializeTag) - : m_address_space_start(Null), m_address_space_end(Null), - m_region_starts{Null, Null, Null, Null}, - m_region_ends{Null, Null, Null, Null}, - m_current_heap_end(Null), m_alias_code_region_start(Null), + : m_address_space_start(Null), m_address_space_end(Null), m_heap_region_start(Null), + m_heap_region_end(Null), m_current_heap_end(Null), m_alias_region_start(Null), + m_alias_region_end(Null), m_stack_region_start(Null), m_stack_region_end(Null), + m_kernel_map_region_start(Null), m_kernel_map_region_end(Null), m_alias_code_region_start(Null), m_alias_code_region_end(Null), m_code_region_start(Null), m_code_region_end(Null), - m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_alias_region_extra_size(), + m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(), @@ -227,7 +220,7 @@ namespace ams::kern { explicit KPageTableBase() { /* ... */ } NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); void Finalize(); @@ -243,25 +236,21 @@ namespace ams::kern { } constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const { - return this->Contains(addr, size) && m_region_starts[RegionType_Alias] <= addr && addr + size - 1 <= m_region_ends[RegionType_Alias] - 1; + return this->Contains(addr, size) && m_alias_region_start <= addr && addr + size - 1 <= m_alias_region_end - 1; } bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { /* Even though Unsafe physical memory is KMemoryState_Normal, it must be mapped inside the alias code region. */ - return this->CanContain(addr, size, ams::svc::MemoryState_AliasCode); + return this->CanContain(addr, size, KMemoryState_AliasCode); } ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() { return KScopedLightLock(m_device_map_lock); } - KProcessAddress GetRegionAddress(ams::svc::MemoryState state) const; - size_t GetRegionSize(ams::svc::MemoryState state) const; - bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const; - - ALWAYS_INLINE KProcessAddress GetRegionAddress(KMemoryState state) const { return this->GetRegionAddress(static_cast(state & KMemoryState_Mask)); } - ALWAYS_INLINE size_t GetRegionSize(KMemoryState state) const { return this->GetRegionSize(static_cast(state & KMemoryState_Mask)); } - ALWAYS_INLINE bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return this->CanContain(addr, size, static_cast(state & KMemoryState_Mask)); } + KProcessAddress GetRegionAddress(KMemoryState state) const; + size_t GetRegionSize(KMemoryState state) const; + bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const; protected: /* NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions */ /* in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived */ @@ -318,8 +307,7 @@ namespace ams::kern { R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr)); } - 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(const KMemoryInfo &info, 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, 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 { R_RETURN(this->CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); @@ -328,16 +316,14 @@ 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); Result QueryInfoImpl(KMemoryInfo *out_info, ams::svc::PageInfo *out_page, KProcessAddress address) const; - Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const; + Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, KMemoryState state) const; - Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, const KPageProperties &properties); + Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm); Result MapPageGroupImpl(PageLinkedList *page_list, KProcessAddress address, const KPageGroup &pg, const KPageProperties properties, bool reuse_ll); void RemapPageGroup(PageLinkedList *page_list, KProcessAddress address, size_t size, const KPageGroup &pg); @@ -349,9 +335,9 @@ namespace ams::kern { NOINLINE Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm); - Result MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryState state, KMemoryPermission perm); - Result ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size, KMemoryState state); - Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size, KMemoryState state); + Result MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm); + Result ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size); + Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size); Result SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state); Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send); @@ -385,8 +371,8 @@ namespace ams::kern { Result SetMaxHeapSize(size_t size); Result QueryInfo(KMemoryInfo *out_info, ams::svc::PageInfo *out_page_info, KProcessAddress addr) const; Result QueryPhysicalAddress(ams::svc::PhysicalMemoryInfo *out, KProcessAddress address) const; - Result QueryStaticMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, ams::svc::MemoryState_Static)); } - Result QueryIoMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, ams::svc::MemoryState_Io)); } + Result QueryStaticMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, KMemoryState_Static)); } + Result QueryIoMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, KMemoryState_Io)); } Result MapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); Result UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); @@ -396,8 +382,8 @@ namespace ams::kern { Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping); Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm); Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm); - Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size); - Result UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size); + Result MapInsecureMemory(KProcessAddress address, size_t size); + Result UnmapInsecureMemory(KProcessAddress address, size_t size); Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm) { R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true, region_start, region_num_pages, state, perm)); @@ -421,13 +407,12 @@ namespace ams::kern { Result MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr); Result InvalidateProcessDataCache(KProcessAddress address, size_t size); - Result InvalidateCurrentProcessDataCache(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 ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); + Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size); Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size); - Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state); + Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size); Result LockForMapDeviceAddressSpace(bool *out_is_io, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned, bool check_heap); Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap); @@ -488,30 +473,24 @@ namespace ams::kern { } public: KProcessAddress GetAddressSpaceStart() const { return m_address_space_start; } - - KProcessAddress GetHeapRegionStart() const { return m_region_starts[RegionType_Heap]; } - KProcessAddress GetAliasRegionStart() const { return m_region_starts[RegionType_Alias]; } - KProcessAddress GetStackRegionStart() const { return m_region_starts[RegionType_Stack]; } - KProcessAddress GetKernelMapRegionStart() const { return m_region_starts[RegionType_KernelMap]; } - + KProcessAddress GetHeapRegionStart() const { return m_heap_region_start; } + KProcessAddress GetAliasRegionStart() const { return m_alias_region_start; } + KProcessAddress GetStackRegionStart() const { return m_stack_region_start; } + KProcessAddress GetKernelMapRegionStart() const { return m_kernel_map_region_start; } KProcessAddress GetAliasCodeRegionStart() const { return m_alias_code_region_start; } - size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } - - size_t GetHeapRegionSize() const { return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; } - size_t GetAliasRegionSize() const { return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; } - size_t GetStackRegionSize() const { return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; } - size_t GetKernelMapRegionSize() const { return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; } - + size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } + size_t GetHeapRegionSize() const { return m_heap_region_end - m_heap_region_start; } + size_t GetAliasRegionSize() const { return m_alias_region_end - m_alias_region_start; } + size_t GetStackRegionSize() const { return m_stack_region_end - m_stack_region_start; } + size_t GetKernelMapRegionSize() const { return m_kernel_map_region_end - m_kernel_map_region_start; } size_t GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } - size_t GetAliasRegionExtraSize() const { return m_alias_region_extra_size; } - size_t GetNormalMemorySize() const { /* Lock the table. */ KScopedLightLock lk(m_general_lock); - return (m_current_heap_end - m_region_starts[RegionType_Heap]) + m_mapped_physical_memory_size; + return (m_current_heap_end - m_heap_region_start) + m_mapped_physical_memory_size; } size_t GetCodeSize() const; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 849f73dab..33adfe097 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -76,7 +76,6 @@ namespace ams::kern { bool m_is_signaled; bool m_is_initialized; bool m_is_application; - bool m_is_default_application_system_resource; char m_name[13]; util::Atomic m_num_running_threads; u32 m_flags; @@ -179,8 +178,6 @@ namespace ams::kern { constexpr bool IsApplication() const { return m_is_application; } - constexpr bool IsDefaultApplicationSystemResource() const { return m_is_default_application_system_resource; } - constexpr bool IsSuspended() const { return m_is_suspended; } constexpr void SetSuspended(bool suspended) { m_is_suspended = suspended; } @@ -206,10 +203,6 @@ namespace ams::kern { return m_capabilities.IsPermittedDebug(); } - constexpr bool CanForceDebugProd() const { - return m_capabilities.CanForceDebugProd(); - } - constexpr bool CanForceDebug() const { return m_capabilities.CanForceDebug(); } @@ -287,20 +280,12 @@ namespace ams::kern { void IncrementRunningThreadCount(); void DecrementRunningThreadCount(); - size_t GetRequiredSecureMemorySizeNonDefault() const { - return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; - } - - size_t GetRequiredSecureMemorySize() const { - return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; - } - size_t GetTotalSystemResourceSize() const { - return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->GetSize() : 0; + return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->GetSize() : 0; } size_t GetUsedSystemResourceSize() const { - return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->GetUsedSize() : 0; + return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->GetUsedSize() : 0; } void SetRunningThread(s32 core, KThread *thread, u64 idle_count, u64 switch_count) { @@ -364,7 +349,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, s64 value, s64 timeout) { + Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s32 value, s64 timeout) { R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout)); } @@ -378,7 +363,7 @@ namespace ams::kern { /* Update the current page table. */ if (next_process) { - next_process->GetPageTable().Activate(next_process->GetSlabIndex(), next_process->GetProcessId()); + next_process->GetPageTable().Activate(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 3d7ea5310..095bff49a 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_uninitialized_random_generator{true}; + static constinit inline bool s_initialized_random_generator; static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize}; static constinit inline KSpinLock s_random_lock; public: @@ -53,7 +53,7 @@ namespace ams::kern { static size_t GetRealMemorySize(); static size_t GetIntendedMemorySize(); static KPhysicalAddress GetKernelPhysicalBaseAddress(KPhysicalAddress base_address); - static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address); + static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out); static bool ShouldIncreaseThreadResourceLimit(); static void TurnOnCpu(u64 core_id, const ams::kern::init::KInitArguments *args); static size_t GetApplicationPoolSize(); @@ -69,7 +69,6 @@ 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 628d1724b..d0ba5ca10 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp @@ -94,11 +94,7 @@ namespace ams::kern { static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const { - if (m_resource_limit != nullptr) { - return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); - } else { - return 0; - } + return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); } 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 949fd45ba..87b72c0fa 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp @@ -24,36 +24,29 @@ namespace ams::kern { friend class KSystemControlBase; friend class KSystemControl; private: - 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; - }; + 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; private: - 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; } + 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; } public: - 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); } + 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; } }; } \ 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 c34ceb8c3..cd88f3abf 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp @@ -48,22 +48,6 @@ 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/include/mesosphere/kern_k_worker_task_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp index cb87f22b6..df0d81ff3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp @@ -25,8 +25,7 @@ namespace ams::kern { static constexpr s32 ExitWorkerPriority = 11; enum WorkerType { - WorkerType_ExitThread, - WorkerType_ExitProcess, + WorkerType_Exit, WorkerType_Count, }; diff --git a/libraries/libmesosphere/libmesosphere.mk b/libraries/libmesosphere/libmesosphere.mk index 79c2c13ed..32db70664 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 +CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto 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 e7f2eb4fa..864da44a5 100644 --- a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc +++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc @@ -79,12 +79,6 @@ 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 { @@ -113,11 +107,6 @@ namespace ams::kern::arch::arm { constexpr size_t Offset = 0; state->icfgr[i] = m_gicd->icfgr[i + Offset]; } - - /* Save spendsgir. */ - for (size_t i = 0; i < util::size(state->spendsgir); ++i) { - state->spendsgir[i] = m_gicd->spendsgir[i]; - } } void KInterruptController::SaveGlobal(GlobalState *state) const { @@ -173,11 +162,6 @@ namespace ams::kern::arch::arm { m_gicd->icenabler[i + Offset] = 0xFFFFFFFF; m_gicd->isenabler[i + Offset] = state->isenabler[i]; } - - /* Restore spendsgir. */ - for (size_t i = 0; i < util::size(state->spendsgir); ++i) { - m_gicd->spendsgir[i] = state->spendsgir[i]; - } } void KInterruptController::RestoreGlobal(const GlobalState *state) const { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp index 401a4d4d7..657af7f52 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp @@ -112,7 +112,7 @@ namespace ams::kern::arch::arm64::cpu { class KCoreBarrierInterruptHandler : public KInterruptHandler { private: util::Atomic m_target_cores; - KLightLock m_lock; + KSpinLock m_lock; public: constexpr KCoreBarrierInterruptHandler() : KInterruptHandler(), m_target_cores(0), m_lock() { /* ... */ } @@ -123,8 +123,11 @@ namespace ams::kern::arch::arm64::cpu { } void SynchronizeCores(u64 core_mask) { + /* Disable dispatch while we synchronize. */ + KScopedDisableDispatch dd; + /* Acquire exclusive access to ourselves. */ - KScopedLightLock lk(m_lock); + KScopedSpinLock lk(m_lock); /* If necessary, force synchronization with other cores. */ if (const u64 other_cores_mask = core_mask & ~(1ul << GetCurrentCoreId()); other_cores_mask != 0) { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index 6c21b455b..ba44e7f2c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -59,9 +59,7 @@ namespace ams::kern::arch::arm64 { EsrEc_BrkInstruction = 0b111100, }; - - - u32 GetInstructionDataSupervisorMode(const KExceptionContext *context, u64 esr) { + constexpr u32 GetInstructionData(const KExceptionContext *context, u64 esr) { /* Check for THUMB usermode */ if ((context->psr & 0x3F) == 0x30) { u32 insn = *reinterpret_cast(context->pc & ~0x1); @@ -76,64 +74,39 @@ namespace ams::kern::arch::arm64 { } } - u32 GetInstructionDataUserMode(const KExceptionContext *context) { - /* Check for THUMB usermode */ - u32 insn = 0; - if ((context->psr & 0x3F) == 0x30) { - u16 insn_high = 0; - if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_high), reinterpret_cast(context->pc & ~0x1), sizeof(insn_high))) { - insn = insn_high; - - /* Check if the instruction was a THUMB mode branch prefix. */ - if (((insn >> 11) & 0b11110) == 0b11110) { - u16 insn_low = 0; - if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_low), reinterpret_cast((context->pc & ~0x1) + sizeof(u16)), sizeof(insn_low))) { - insn = (static_cast(insn_high) << 16) | (static_cast(insn_low) << 0); - } else { - insn = 0; - } - } - } else { - insn = 0; - } - } else { - 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; - } - } - return insn; - } - - 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; - } - } - } - + void HandleUserException(KExceptionContext *context, u64 esr, u64 far, u64 afsr0, u64 afsr1, u32 data) { 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); @@ -184,7 +157,7 @@ namespace ams::kern::arch::arm64 { } /* Save the debug parameters to the current thread. */ - GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data); + GetCurrentThread().SaveDebugParams(far, esr, data); /* Get the exception type. */ u32 type; @@ -217,13 +190,6 @@ namespace ams::kern::arch::arm64 { type = ams::svc::ExceptionType_InstructionAbort; break; case EsrEc_DataAbortEl0: - /* If esr.IFSC is "Alignment Fault", return UnalignedData instead of DataAbort. */ - if ((esr & 0x3F) == 0b100001) { - type = ams::svc::ExceptionType_UnalignedData; - } else { - type = ams::svc::ExceptionType_DataAbort; - } - break; default: type = ams::svc::ExceptionType_DataAbort; break; @@ -406,6 +372,7 @@ 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. */ @@ -450,28 +417,9 @@ 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 (ec) { + switch ((esr >> 26) & 0x3F) { case EsrEc_Unknown: case EsrEc_IllegalExecution: case EsrEc_BkptInstruction: @@ -553,10 +501,9 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(!KInterruptManager::AreInterruptsEnabled()); /* Retrieve information about the exception. */ - const bool is_user_mode = (context->psr & 0xF) == 0; - const u64 esr = cpu::GetEsrEl1(); - const u64 afsr0 = cpu::GetAfsr0El1(); - const u64 afsr1 = cpu::GetAfsr1El1(); + const u64 esr = cpu::GetEsrEl1(); + const u64 afsr0 = cpu::GetAfsr0El1(); + const u64 afsr1 = cpu::GetAfsr1El1(); u64 far = 0; u32 data = 0; @@ -567,12 +514,7 @@ namespace ams::kern::arch::arm64 { case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: far = context->pc; - /* NOTE: Nintendo always calls GetInstructionDataUserMode. */ - if (is_user_mode) { - data = GetInstructionDataUserMode(context); - } else { - data = GetInstructionDataSupervisorMode(context, esr); - } + data = GetInstructionData(context, esr); break; case EsrEc_Svc32: if (context->psr & 0x20) { @@ -601,6 +543,7 @@ namespace ams::kern::arch::arm64 { /* Verify that spsr's M is allowable (EL0t). */ { + const bool is_user_mode = (context->psr & 0xF) == 0; if (is_user_mode) { /* If the user disable count is set, we may need to pin the current thread. */ if (GetCurrentThread().GetUserDisableCount() != 0 && GetCurrentProcess().GetPinnedThread(GetCurrentCoreId()) == nullptr) { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 87d7bf307..3addd8da1 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -15,28 +15,6 @@ */ #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 { @@ -387,7 +365,7 @@ namespace ams::kern::arch::arm64 { value = 0; } - /* Set the watchpoint. */ + /* Set the watchkpoint. */ switch (name) { case ams::svc::HardwareBreakPointRegisterName_D0: MESOSPHERE_SET_HW_WATCH_POINT( 0, flags, value); break; case ams::svc::HardwareBreakPointRegisterName_D1: MESOSPHERE_SET_HW_WATCH_POINT( 1, flags, value); break; @@ -645,6 +623,11 @@ namespace ams::kern::arch::arm64 { } } + /* Read the first instruction. */ + if (!ReadValue(std::addressof(temp_32), process, base_address)) { + return PrintAddress(address); + } + /* Get the module name. */ char module_name[0x20]; const bool has_module_name = GetModuleName(module_name, sizeof(module_name), process, base_address); @@ -654,32 +637,36 @@ namespace ams::kern::arch::arm64 { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - /* Locate .dyn using rocrt::ModuleHeader. */ - { - /* Determine the ModuleHeader offset. */ + if (temp_32 == 0) { + /* Module is dynamically loaded by rtld. */ u32 mod_offset; if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - - /* Read the signature. */ - constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + SignatureFieldOffset)) { + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset)) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - - /* Check that the module signature is expected. */ - if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ + if (temp_32 != 0x30444F4D) { /* MOD0 */ return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - - /* Determine the dynamic offset. */ - constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + DynamicFieldOffset)) { + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + sizeof(u32))) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - dyn_address = base_address + mod_offset + temp_32; + } else if (temp_32 == 0x14000002) { + /* Module embeds rtld. */ + if (!ReadValue(std::addressof(temp_32), process, base_address + 0x5C)) { + return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); + } + if (temp_32 != 0x94000002) { + return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); + } + if (!ReadValue(std::addressof(temp_32), process, base_address + 0x60)) { + return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); + } + dyn_address = base_address + 0x60 + temp_32; + } else { + return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } /* 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 abc3b1076..ae569f998 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -85,6 +85,77 @@ 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 { @@ -113,7 +184,6 @@ namespace ams::kern::arch::arm64 { this->OnKernelTableSinglePageUpdated(virt_addr); } - void KPageTable::Initialize(s32 core_id) { /* Nothing actually needed here. */ MESOSPHERE_UNUSED(core_id); @@ -124,29 +194,41 @@ 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, 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)); + Result KPageTable::InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + /* The input ID isn't actually used. */ + MESOSPHERE_UNUSED(id); + + /* Get an ASID */ + m_asid = g_asid_manager.Reserve(); + ON_RESULT_FAILURE { g_asid_manager.Release(m_asid); }; /* Set our manager. */ m_manager = system_resource->GetPageTableManagerPointer(); - /* 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); + /* 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); }; /* Initialize our base table. */ - const size_t as_width = GetAddressSpaceWidth(flags); + const size_t as_width = GetAddressSpaceWidth(as_type); const KProcessAddress as_start = 0; const KProcessAddress as_end = (1ul << as_width); - R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(ttbr0_virt), as_start, as_end, code_address, code_size, system_resource, resource_limit)); + R_TRY(KPageTableBase::InitializeForProcess(as_type, enable_aslr, enable_das_merge, from_back, pool, GetVoidPointer(new_table), 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(); @@ -157,15 +239,9 @@ namespace ams::kern::arch::arm64 { /* Only process tables should be finalized. */ MESOSPHERE_ASSERT(!this->IsKernel()); - /* NOTE: Here Nintendo calls an unknown OnFinalize function. */ - /* this->OnFinalize(); */ - /* Note that we've updated (to ensure we're synchronized). */ this->NoteUpdated(); - /* NOTE: Here Nintendo calls a second unknown OnFinalize function. */ - /* this->OnFinalize2(); */ - /* Free all pages in the table. */ { /* Get implementation objects. */ @@ -174,104 +250,94 @@ 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 entry; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; + bool cur_valid = false; + TraversalEntry next_entry; + bool next_valid; + size_t tot_size = 0; - KPhysicalAddress cur_phys_addr = Null; - size_t cur_size = 0; - u8 has_attr = 0; + next_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), this->GetAddressSpaceStart()); - bool cur_valid = impl.BeginTraversal(std::addressof(entry), std::addressof(context), this->GetAddressSpaceStart()); + /* Iterate over entries. */ while (true) { - 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; - } + if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) { + 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); } - /* 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; - } + /* Update tracking variables. */ + tot_size += cur_entry.block_size; + cur_entry = next_entry; + cur_valid = next_valid; } - /* Continue the traversal. */ - cur_valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); - - if (entry.block_size == 0) { + if (cur_entry.block_size + tot_size >= as_size) { break; } + + next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); } - /* Free any remaining pages. */ - if (cur_size > 0) { - mm.Close(cur_phys_addr, cur_size / PageSize); + /* Handle the last block. */ + if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { + mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); } } - /* Clear the L1 table. */ + /* 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. */ { 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(); } @@ -282,7 +348,7 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); MESOSPHERE_ASSERT(this->ContainsPages(virt_addr, num_pages)); - if (operation == OperationType_Map) { + if (operation == OperationType_Map || operation == OperationType_MapFirst) { MESOSPHERE_ABORT_UNLESS(is_pa_valid); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); } else { @@ -292,17 +358,25 @@ 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) { - R_RETURN(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); + 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(); } 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_MapFirst: + R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirst, 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)); case OperationType_ChangePermissionsAndRefresh: @@ -325,27 +399,214 @@ namespace ams::kern::arch::arm64 { auto entry_template = this->GetEntryTemplate(properties); 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)); + R_RETURN(this->MapGroup(virt_addr, page_group, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, 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) { - R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); + 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)); + } } /* Cache initial addresses for use on cleanup. */ @@ -375,7 +636,10 @@ 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->SeparatePagesImpl(std::addressof(next_entry), std::addressof(context), virt_addr, remaining_pages * PageSize, page_list, reuse_ll)); + 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); } /* Check that our state is coherent. */ @@ -383,45 +647,87 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(next_entry.phys_addr), next_entry.block_size)); /* Unmap the block. */ - 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; + L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); + switch (next_entry.block_size) { + case L1BlockSize: + { + /* Clear the entry. */ + *l1_entry = InvalidL1PageTableEntry; } - 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; - /* Advance; we will not be working with blocks any more. */ - context.level = static_cast(util::ToUnderlying(context.level) + 1); - freeing_table = true; + /* 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(); } /* Close the blocks. */ @@ -435,20 +741,8 @@ namespace ams::kern::arch::arm64 { } /* Advance. */ - 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; - + virt_addr += next_entry.block_size; + remaining_pages -= next_entry.block_size / PageSize; next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); } @@ -462,127 +756,7 @@ 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) { + Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Cache initial addresses for use on cleanup. */ @@ -643,21 +817,31 @@ namespace ams::kern::arch::arm64 { } /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, num_pages, page_list); + 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(); /* Open references to the pages, if we should. */ if (IsHeapPhysicalAddress(orig_phys_addr)) { - Kernel::GetMemoryManager().Open(orig_phys_addr, num_pages); + if (not_first) { + Kernel::GetMemoryManager().Open(orig_phys_addr, num_pages); + } else { + Kernel::GetMemoryManager().OpenFirst(orig_phys_addr, num_pages); + } } R_SUCCEED(); } - Result KPageTable::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) { + Result KPageTable::MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* We want to maintain a new reference to every page in the group. */ - KScopedPageGroup spg(pg, not_first); + KScopedPageGroup spg(pg); /* Cache initial address for use on cleanup. */ const KProcessAddress orig_virt_addr = virt_addr; @@ -735,130 +919,336 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(mapped_pages == num_pages); /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, num_pages, page_list); + 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(); /* We succeeded! We want to persist the reference to the pages. */ spg.CancelClose(); R_SUCCEED(); } - bool KPageTable::MergePages(TraversalContext *context, PageLinkedList *page_list) { + bool KPageTable::MergePages(KProcessAddress virt_addr, PageLinkedList *page_list) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); - - /* Iteratively merge, until we can't. */ bool merged = false; - while (true) { - /* Try to merge. */ - KVirtualAddress freed_table = Null; - if (!impl.MergePages(std::addressof(freed_table), context, &KPageTable::NoteUpdatedCallback, this)) { - break; + + /* 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; } - /* Free the page. */ - if (freed_table != Null) { - ClearPageTable(freed_table); - this->FreePageTable(page_list, freed_table); + /* 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; } - /* We performed at least one merge. */ + /* 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(); 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; } - void KPageTable::MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list) { + Result KPageTable::SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); - /* Begin traversal. */ - TraversalContext context; - TraversalEntry entry; - MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(context), virt_addr)); + /* 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); - /* Merge start of the range. */ - this->MergePages(std::addressof(context), page_list); + /* 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(); - /* 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)); + /* 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); - /* 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()); + /* 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); } - /* Separate. */ - impl.SeparatePages(entry, context, virt_addr, GetPointer(table), &KPageTable::NoteUpdatedCallback, this); + /* 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(); } + /* 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 num_pages, PageLinkedList *page_list, bool reuse_ll) { + Result KPageTable::SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - auto &impl = this->GetImpl(); + /* If we fail while separating, re-merge. */ + ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - /* 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(); + /* Try to separate pages. */ + R_RETURN(this->SeparatePagesImpl(virt_addr, block_size, page_list, reuse_ll)); } 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. */ - R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); + 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)); + } /* ===================================================== */ @@ -947,15 +1337,59 @@ namespace ams::kern::arch::arm64 { } /* Apply the entry template. */ - { - const size_t num_entries = context.is_contiguous ? BlocksPerContiguousBlock : 1; + 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; - 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); - } + /* 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(); } /* If our option asks us to, try to merge mappings. */ @@ -965,7 +1399,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(std::addressof(context), page_list); + merge = this->MergePages(cur_virt_addr, page_list); } else { merge = false; } @@ -976,7 +1410,7 @@ namespace ams::kern::arch::arm64 { /* If we merged, correct the traversal to a sane state. */ if (merge) { - /* NOTE: Begin a new traversal, now that we've merged. */ + /* NOTE: Nintendo does not verify the result of this BeginTraversal call. */ 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. */ @@ -1021,13 +1455,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, num_pages, page_list); + this->MergePages(virt_addr, page_list); + if (num_pages > 1) { + this->MergePages(virt_addr + (num_pages - 1) * PageSize, 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 5ce64e3f6..95c7d7a64 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,59 +21,6 @@ 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) { @@ -86,10 +33,95 @@ 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(); + + return true; + } else { + out_entry->phys_addr = Null; + out_entry->block_size = L3BlockSize; + out_entry->sw_reserved_bits = 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(); + + /* 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_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_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 = {}; - *out_context = {}; + out_entry->phys_addr = Null; + out_entry->block_size = L1BlockSize; + out_entry->sw_reserved_bits = 0; + out_context->l1_entry = m_table + m_num_entries; + out_context->l2_entry = nullptr; + out_context->l3_entry = nullptr; /* Validate that we can read the actual entry. */ const size_t l0_index = GetL0Index(address); @@ -106,78 +138,124 @@ namespace ams::kern::arch::arm64 { } } - /* 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); + /* Extract the entry. */ + const bool valid = this->ExtractL1Entry(out_entry, out_context, this->GetL1Entry(address), address); - /* 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; + /* 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(); } - /* 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(); + return valid; } bool KPageTableImpl::ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const { - /* 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)); + bool valid = false; - /* Set the pte. */ - context->level_entries[context->level] = next_pte; + /* 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); - /* 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 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); - /* 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 = {}; + 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; + context->l1_entry = m_table + m_num_entries; + context->l2_entry = nullptr; + context->l3_entry = nullptr; 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(); + } } - /* 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(); + return valid; } bool KPageTableImpl::GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const { @@ -196,147 +274,32 @@ namespace ams::kern::arch::arm64 { } } - /* 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 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; } - 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 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; } - 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; + /* 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 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); + return false; } void KPageTableImpl::Dump(uintptr_t start, size_t size) const { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp index 5f5112f8d..23e3541de 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp @@ -18,8 +18,12 @@ namespace ams::kern::arch::arm64 { void KSupervisorPageTable::Initialize(s32 core_id) { - /* Verify that sctlr_el1 has the wxn bit set. */ - MESOSPHERE_ABORT_UNLESS(cpu::SystemControlRegisterAccessor().GetWxn()); + /* Get the identity mapping ttbr0. */ + m_ttbr0_identity[core_id] = cpu::GetTtbr0El1(); + + /* Set sctlr_el1 */ + cpu::SystemControlRegisterAccessor().SetWxn(true).Store(); + cpu::EnsureInstructionConsistency(); /* Invalidate the entire TLB. */ cpu::InvalidateEntireTlb(); 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 76e91cff7..b3cef6755 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -21,15 +21,6 @@ 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 1d9d2c5da..5b1fd4a51 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::Impl::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -48,12 +48,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -72,7 +72,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -87,12 +87,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPv mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -111,7 +111,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -126,26 +126,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPv mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, %function .balign 0x10 -_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: +_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: /* Just load and store a u32. */ ldtr w2, [x1] str w2, [x0] @@ -154,27 +140,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, %function .balign 0x10 -_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: +_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -204,12 +175,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm: mov x0, #0 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -228,12 +199,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -252,7 +223,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -267,12 +238,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPK mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -291,7 +262,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -306,12 +277,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPK mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv: /* Just load and store a u32. */ ldr w2, [x1] sttr w2, [x0] @@ -320,12 +291,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::CopyStringToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -355,12 +326,114 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm: mov x0, #0 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::ClearMemory(void *dst, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj: +_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: /* Load the value from the address. */ ldaxr w4, [x1] @@ -375,7 +448,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj: stlxr w6, w5, [x1] /* If we failed to store, try again. */ - cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj + cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj /* We're done. */ str w4, [x0] @@ -383,12 +456,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj: ret -/* 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 +/* 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 .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii: +_ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii: /* Load the value from the address. */ ldaxr w4, [x1] @@ -406,19 +479,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii: stlxr w5, w3, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii 2: /* We're done. */ str w4, [x0] mov x0, #1 ret -/* 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 +/* 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 .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i: +_ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i: /* Load the value from the address. */ ldaxr w3, [x1] @@ -437,19 +510,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i: stlxr w5, w4, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i 2: /* We're done. */ str w3, [x0] mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::StoreDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::StoreDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -464,12 +537,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::FlushDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::FlushDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -484,12 +557,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::Impl::InvalidateDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::InvalidateDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -504,12 +577,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -554,12 +627,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -604,12 +677,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -654,12 +727,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -699,12 +772,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -744,12 +817,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm: mov x0, #1 ret -/* 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 +/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm: /* 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 deleted file mode 100644 index f82db4454..000000000 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s +++ /dev/null @@ -1,67 +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 . - */ - -/* 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_exception_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s index c3ee6a077..2194c594d 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s @@ -130,4 +130,4 @@ _ZN3ams4kern3svc14RestoreContextEm: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - ERET_WITH_SPECULATION_BARRIER + eret diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s index a3ee735a2..d795c6aae 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s @@ -68,8 +68,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Check if our disable count allows us to call SVCs. */ mrs x10, tpidrro_el0 - add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT) - ldtrh w10, [x10] + ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)] cbz w10, 1f /* It might not, so check the stack params to see if we must not allow the SVC. */ @@ -195,7 +194,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - ERET_WITH_SPECULATION_BARRIER + eret 5: /* Return from SVC. */ @@ -298,7 +297,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::SvcHandler32() */ .section .text._ZN3ams4kern4arch5arm6412SvcHandler32Ev, "ax", %progbits @@ -353,8 +352,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Check if our disable count allows us to call SVCs. */ mrs x10, tpidrro_el0 - add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT) - ldtrh w10, [x10] + ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)] cbz w10, 1f /* It might not, so check the stack params to see if we must not allow the SVC. */ @@ -469,7 +467,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - ERET_WITH_SPECULATION_BARRIER + eret 5: /* Return from SVC. */ @@ -549,4 +547,4 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - ERET_WITH_SPECULATION_BARRIER + eret 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 cfc0cb7c5..aec27c4ba 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp @@ -36,10 +36,6 @@ 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 @@ -85,8 +81,6 @@ namespace ams::kern::svc { table[svc::SvcId_CallSecureMonitor] = CallCallSecureMonitor64From32; - table[svc::SvcId_WaitForAddress] = CallWaitForAddress64From32; - return table; }(); @@ -103,8 +97,6 @@ namespace ams::kern::svc { table[svc::SvcId_ReturnFromException] = CallReturnFromException64; - table[svc::SvcId_WaitForAddress] = CallWaitForAddress64; - return table; }(); @@ -150,10 +142,10 @@ namespace ams::kern::svc { /* Get the target firmware. */ const auto target_fw = kern::GetTargetFirmware(); - /* 10.0.0 broke the ABI for QueryIoMapping, and renamed it to QueryMemoryMapping. */ + /* 10.0.0 broke the ABI for QueryIoMapping. */ if (target_fw < TargetFirmware_10_0_0) { - if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_QueryMemoryMapping, LegacyQueryIoMapping::Call64); } - if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_QueryMemoryMapping, LegacyQueryIoMapping::Call64From32); } + if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64); } + if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64From32); } } /* 6.0.0 broke the ABI for GetFutureThreadInfo, and renamed it to GetDebugFutureThreadInfo. */ 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 292c25750..f70bcbb97 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(phys_addr == Null || IsHeapPhysicalAddress(phys_addr)); + MESOSPHERE_ASSERT(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 59e7770ea..00b606ff5 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,6 +31,8 @@ namespace ams::kern::board::nintendo::nx { /* Struct representing registers saved on wake/sleep. */ class SavedSystemRegisters { private: + u64 ttbr0_el1; + u64 tcr_el1; u64 elr_el1; u64 sp_el0; u64 spsr_el1; @@ -89,6 +91,8 @@ namespace ams::kern::board::nintendo::nx { void SavedSystemRegisters::Save() { /* Save system registers. */ + this->ttbr0_el1 = cpu::GetTtbr0El1(); + this->tcr_el1 = cpu::GetTcrEl1(); this->tpidr_el0 = cpu::GetTpidrEl0(); this->elr_el1 = cpu::GetElrEl1(); this->sp_el0 = cpu::GetSpEl0(); @@ -403,7 +407,8 @@ namespace ams::kern::board::nintendo::nx { cpu::EnsureInstructionConsistency(); /* Restore system registers. */ - cpu::SetTtbr0El1 (KPageTable::GetKernelTtbr0()); + cpu::SetTtbr0El1 (this->ttbr0_el1); + cpu::SetTcrEl1 (this->tcr_el1); cpu::SetTpidrEl0 (this->tpidr_el0); cpu::SetElrEl1 (this->elr_el1); cpu::SetSpEl0 (this->sp_el0); @@ -510,6 +515,24 @@ namespace ams::kern::board::nintendo::nx { /* Save the system registers for the current core. */ g_sleep_system_registers[core_id].Save(); + /* Change the translation tables to use the kernel table. */ + { + /* Get the current value of the translation control register. */ + const u64 tcr = cpu::GetTcrEl1(); + + /* Disable translation table walks on tlb miss. */ + cpu::TranslationControlRegisterAccessor(tcr).SetEpd0(true).Store(); + cpu::EnsureInstructionConsistency(); + + /* Change the translation table base (ttbr0) to use the kernel table. */ + cpu::SetTtbr0El1(Kernel::GetKernelPageTable().GetIdentityMapTtbr0(core_id)); + cpu::EnsureInstructionConsistency(); + + /* Enable translation table walks on tlb miss. */ + cpu::TranslationControlRegisterAccessor(tcr).SetEpd0(false).Store(); + cpu::EnsureInstructionConsistency(); + } + /* Invalidate the entire tlb. */ cpu::InvalidateEntireTlb(); @@ -524,27 +547,18 @@ namespace ams::kern::board::nintendo::nx { /* Ensure that all cores get to this point before continuing. */ cpu::SynchronizeAllCores(); - /* Wait 100us before continuing. */ - { - const s64 timeout = KHardwareTimer::GetTick() + ams::svc::Tick(TimeSpan::FromMicroSeconds(100)); - while (KHardwareTimer::GetTick() < timeout) { - __asm__ __volatile__("" ::: "memory"); - } - } - /* Save the interrupt manager's state. */ Kernel::GetInterruptManager().Save(core_id); /* Setup the initial arguments. */ { - /* Determine whether we're running on a cortex-a53 or a-57. */ - cpu::MainIdRegisterAccessor midr_el1; - const auto implementer = midr_el1.GetImplementer(); - const auto primary_part = midr_el1.GetPrimaryPartNumber(); - const bool needs_cpu_ctlr = (implementer == cpu::MainIdRegisterAccessor::Implementer::ArmLimited) && (primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA57 || primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA53); - - init_args->cpuactlr = needs_cpu_ctlr ? cpu::GetCpuActlrEl1() : 0; - init_args->cpuectlr = needs_cpu_ctlr ? cpu::GetCpuEctlrEl1() : 0; + init_args->ttbr0 = cpu::GetTtbr0El1(); + init_args->ttbr1 = cpu::GetTtbr1El1(); + init_args->tcr = cpu::GetTcrEl1(); + init_args->mair = cpu::GetMairEl1(); + init_args->cpuactlr = cpu::GetCpuActlrEl1(); + init_args->cpuectlr = cpu::GetCpuEctlrEl1(); + init_args->sctlr = cpu::GetSctlrEl1(); init_args->sp = 0; init_args->entrypoint = reinterpret_cast(::ams::kern::board::nintendo::nx::KSleepManager::ResumeEntry); init_args->argument = sleep_buffer; 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 58e86f152..e3ac52278 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 const volatile bool g_call_smc_on_panic = false; + constinit bool g_call_smc_on_panic; /* Global variables for secure memory. */ constinit KSpinLock g_secure_applet_lock; @@ -296,7 +296,7 @@ namespace ams::kern::board::nintendo::nx { /* TODO: Move this into a header for the MC in general. */ constexpr u32 MemoryControllerConfigurationRegister = 0x70019050; u32 config_value; - smc::init::ReadWriteRegister(std::addressof(config_value), MemoryControllerConfigurationRegister, 0, 0); + MESOSPHERE_INIT_ABORT_UNLESS(smc::init::ReadWriteRegister(&config_value, MemoryControllerConfigurationRegister, 0, 0)); return static_cast(config_value & 0x3FFF) << 20; } @@ -361,9 +361,7 @@ namespace ams::kern::board::nintendo::nx { }(); /* Return (possibly) adjusted size. */ - /* 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; + constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB; return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; } @@ -389,7 +387,7 @@ namespace ams::kern::board::nintendo::nx { } void KSystemControl::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { - MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn(core_id, entrypoint, arg)) == 0); + MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn(core_id, entrypoint, arg)) == 0); } /* Randomness for Initialization. */ @@ -403,67 +401,34 @@ namespace ams::kern::board::nintendo::nx { } /* System Initialization. */ - void KSystemControl::ConfigureKTargetSystem() { + void KSystemControl::InitializePhase1() { /* Configure KTargetSystem. */ - volatile auto *ts = const_cast(std::addressof(KTargetSystem::s_data)); { - /* Set whether we're in debug mode. */ + /* Set IsDebugMode. */ { - ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode); + KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::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; + /* If debug mode, we want to initialize uart logging. */ + KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode()); } /* Set Kernel Configuration. */ { const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; - 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(); + KTargetSystem::EnableDebugMemoryFill(kernel_config.Get()); + KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get()); + KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get()); + KTargetSystem::EnableUserPmuAccess(kernel_config.Get()); - /* Configure call smc on panic. */ - *const_cast(std::addressof(g_call_smc_on_panic)) = kernel_config.Get(); + 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. */ - 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)); + KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification)); } } @@ -526,7 +491,7 @@ namespace ams::kern::board::nintendo::nx { KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(!s_uninitialized_random_generator)) { + if (AMS_LIKELY(s_initialized_random_generator)) { return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); } else { return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc); @@ -537,7 +502,7 @@ namespace ams::kern::board::nintendo::nx { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(!s_uninitialized_random_generator)) { + if (AMS_LIKELY(s_initialized_random_generator)) { return s_random_generator.GenerateRandomU64(); } else { return GenerateRandomU64FromSmc(); @@ -625,15 +590,19 @@ 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) { /* If we should, instruct the secure monitor to display a panic screen. */ - smc::ShowError(0xF00); + smc::Panic(0xF00); } - AMS_INFINITE_LOOP(); } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp index d55eb2c70..6b1e3923f 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp @@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx::smc { enum FunctionId : u32 { FunctionId_GetConfig = 0xC3000004, FunctionId_GenerateRandomBytes = 0xC3000005, - FunctionId_ShowError = 0xC3000006, + FunctionId_Panic = 0xC3000006, FunctionId_ConfigureCarveout = 0xC3000007, FunctionId_ReadWriteRegister = 0xC3000008, @@ -51,187 +51,122 @@ namespace ams::kern::board::nintendo::nx::smc { FunctionId_SetConfig = 0xC3000409, }; - constexpr size_t GenerateRandomBytesSizeMax = sizeof(::ams::svc::lp64::SecureMonitorArguments) - sizeof(::ams::svc::lp64::SecureMonitorArguments{}.r[0]); - /* Global lock for generate random bytes. */ constinit KSpinLock g_generate_random_lock; - bool TryGetConfigImpl(u64 *out, size_t num_qwords, ConfigItem config_item) { - /* Create the arguments .*/ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* If successful, copy the output. */ - const bool success = static_cast(args.r[0]) == SmcResult::Success; - if (AMS_LIKELY(success)) { - for (size_t i = 0; i < num_qwords && i < 7; i++) { - out[i] = args.r[1 + i]; - } - } - - return success; - } - - bool SetConfigImpl(ConfigItem config_item, u64 value) { - /* Create the arguments .*/ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast(config_item), 0, value } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* Return whether the call was successful. */ - return static_cast(args.r[0]) == SmcResult::Success; - } - - bool ReadWriteRegisterImpl(u32 *out, u64 address, u32 mask, u32 value) { - /* Create the arguments .*/ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* Unconditionally write the output. */ - *out = static_cast(args.r[1]); - - /* Return whether the call was successful. */ - return static_cast(args.r[0]) == SmcResult::Success; - } - - bool GenerateRandomBytesImpl(void *dst, size_t size) { - /* Create the arguments. */ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* If successful, copy the output. */ - const bool success = static_cast(args.r[0]) == SmcResult::Success; - if (AMS_LIKELY(success)) { - std::memcpy(dst, std::addressof(args.r[1]), size); - } - - return success; - } - - bool ConfigureCarveoutImpl(size_t which, uintptr_t address, size_t size) { - /* Create the arguments .*/ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast(which), static_cast(address), static_cast(size) } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* Return whether the call was successful. */ - return static_cast(args.r[0]) == SmcResult::Success; - } - - bool ShowErrorImpl(u32 color) { - /* Create the arguments .*/ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ShowError, color } }; - - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - /* Return whether the call was successful. */ - return static_cast(args.r[0]) == SmcResult::Success; - } - - void CallSecureMonitorFromUserImpl(ams::svc::lp64::SecureMonitorArguments *args) { - /* Call into the secure monitor. */ - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args->r); - } - } /* SMC functionality needed for init. */ namespace init { void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { - /* Ensure we successfully get the config. */ - MESOSPHERE_INIT_ABORT_UNLESS(TryGetConfigImpl(out, num_qwords, config_item)); + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; + + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); + + for (size_t i = 0; i < num_qwords && i < 7; i++) { + out[i] = args.r[1 + i]; + } } void GenerateRandomBytes(void *dst, size_t size) { - /* Check that the size is valid. */ - MESOSPHERE_INIT_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax); + /* Call SmcGenerateRandomBytes() */ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; + MESOSPHERE_INIT_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0])); - /* Ensure we successfully generate the random bytes. */ - MESOSPHERE_INIT_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size)); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); + + /* Copy output. */ + std::memcpy(dst, std::addressof(args.r[1]), size); } - void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) { - /* Ensure we successfully access the register. */ - MESOSPHERE_INIT_ABORT_UNLESS(ReadWriteRegisterImpl(out, address, mask, value)); + bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) { + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; + + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); + + *out = args.r[1]; + + return static_cast(args.r[0]) == SmcResult::Success; } } bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { - /* Disable interrupts. */ - KScopedInterruptDisable di; + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; - /* Get the config. */ - return TryGetConfigImpl(out, num_qwords, config_item); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + if (AMS_UNLIKELY(static_cast(args.r[0]) != SmcResult::Success)) { + return false; + } + + for (size_t i = 0; i < num_qwords && i < 7; i++) { + out[i] = args.r[1 + i]; + } + + return true; } void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { - /* Ensure we successfully get the config. */ MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item)); } bool SetConfig(ConfigItem config_item, u64 value) { - /* Disable interrupts. */ - KScopedInterruptDisable di; + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast(config_item), 0, value } }; - /* Set the config. */ - return SetConfigImpl(config_item, value); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + return static_cast(args.r[0]) == SmcResult::Success; } bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) { - /* Disable interrupts. */ - KScopedInterruptDisable di; + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; - /* Access the register. */ - return ReadWriteRegisterImpl(out, address, mask, value); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + *out = static_cast(args.r[1]); + return static_cast(args.r[0]) == SmcResult::Success; } void ConfigureCarveout(size_t which, uintptr_t address, size_t size) { - /* Disable interrupts. */ - KScopedInterruptDisable di; + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast(which), static_cast(address), static_cast(size) } }; - /* Ensure that we successfully configure the carveout. */ - MESOSPHERE_ABORT_UNLESS(ConfigureCarveoutImpl(which, address, size)); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + MESOSPHERE_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); } void GenerateRandomBytes(void *dst, size_t size) { - /* Check that the size is valid. */ - MESOSPHERE_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax); + /* Setup for call. */ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; + MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0])); - /* Disable interrupts. */ - KScopedInterruptDisable di; + /* Make call. */ + { + KScopedInterruptDisable intr_disable; + KScopedSpinLock lk(g_generate_random_lock); - /* Acquire the exclusive right to generate random bytes. */ - KScopedSpinLock lk(g_generate_random_lock); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + } + MESOSPHERE_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); - /* Ensure we successfully generate the random bytes. */ - MESOSPHERE_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size)); + /* Copy output. */ + std::memcpy(dst, std::addressof(args.r[1]), size); } - void ShowError(u32 color) { - /* Disable interrupts. */ - KScopedInterruptDisable di; + void NORETURN Panic(u32 color) { + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_Panic, color } }; - /* Ensure we successfully show the error. */ - MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color)); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + AMS_INFINITE_LOOP(); } void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) { - /* Disable interrupts. */ - KScopedInterruptDisable di; - - /* Perform the call. */ - CallSecureMonitorFromUserImpl(args); + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args->r); } } \ No newline at end of file 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 6ee325aa3..b172fa540 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -98,10 +98,9 @@ namespace ams::kern::board::nintendo::nx::smc { }; enum UserRebootType { - UserRebootType_None = 0, - UserRebootType_ToRcm = 1, - UserRebootType_ToPayload = 2, - UserRebootType_ToFatalError = 3, + UserRebootType_None = 0, + UserRebootType_ToRcm = 1, + UserRebootType_ToPayload = 2, }; void GenerateRandomBytes(void *dst, size_t size); @@ -112,7 +111,7 @@ namespace ams::kern::board::nintendo::nx::smc { bool SetConfig(ConfigItem config_item, u64 value); - void ShowError(u32 color); + void NORETURN Panic(u32 color); void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args); @@ -120,7 +119,7 @@ namespace ams::kern::board::nintendo::nx::smc { void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item); void GenerateRandomBytes(void *dst, size_t size); - void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value); + bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value); } diff --git a/libraries/libmesosphere/source/init/kern_init_elf.cpp b/libraries/libmesosphere/source/init/kern_init_elf.cpp index a9ef3666d..96ac6b5ee 100644 --- a/libraries/libmesosphere/source/init/kern_init_elf.cpp +++ b/libraries/libmesosphere/source/init/kern_init_elf.cpp @@ -21,13 +21,10 @@ namespace ams::kern::init::Elf { void ApplyRelocations(uintptr_t base_address, const Dyn *dynamic) { uintptr_t dyn_rel = 0; uintptr_t dyn_rela = 0; - uintptr_t dyn_relr = 0; uintptr_t rel_count = 0; uintptr_t rela_count = 0; - uintptr_t relr_sz = 0; uintptr_t rel_ent = 0; uintptr_t rela_ent = 0; - uintptr_t relr_ent = 0; /* Iterate over all tags, identifying important extents. */ for (const Dyn *cur_entry = dynamic; cur_entry->GetTag() != DT_NULL; cur_entry++) { @@ -38,99 +35,43 @@ namespace ams::kern::init::Elf { case DT_RELA: dyn_rela = base_address + cur_entry->GetPtr(); break; - case DT_RELR: - dyn_relr = base_address + cur_entry->GetPtr(); - break; case DT_RELENT: rel_ent = cur_entry->GetValue(); break; case DT_RELAENT: rela_ent = cur_entry->GetValue(); break; - case DT_RELRENT: - relr_ent = cur_entry->GetValue(); - break; case DT_RELCOUNT: rel_count = cur_entry->GetValue(); break; case DT_RELACOUNT: rela_count = cur_entry->GetValue(); break; - case DT_RELRSZ: - relr_sz = cur_entry->GetValue(); - break; } } /* Apply all Rel relocations */ - if (rel_count > 0) { - /* Check that the rel relocations are applyable. */ - MESOSPHERE_INIT_ABORT_UNLESS(dyn_rel != 0); - MESOSPHERE_INIT_ABORT_UNLESS(rel_ent == sizeof(Elf::Rel)); + for (size_t i = 0; i < rel_count; i++) { + const auto &rel = *reinterpret_cast(dyn_rel + rel_ent * i); - for (size_t i = 0; i < rel_count; ++i) { - const auto &rel = reinterpret_cast(dyn_rel)[i]; + /* Only allow architecture-specific relocations. */ + while (rel.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } - /* Only allow architecture-specific relocations. */ - while (rel.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } - - /* Apply the relocation. */ - Elf::Addr *target_address = reinterpret_cast(base_address + rel.GetOffset()); - *target_address += base_address; - } + /* Apply the relocation. */ + Elf::Addr *target_address = reinterpret_cast(base_address + rel.GetOffset()); + *target_address += base_address; } /* Apply all Rela relocations. */ - if (rela_count > 0) { - /* Check that the rela relocations are applyable. */ - MESOSPHERE_INIT_ABORT_UNLESS(dyn_rela != 0); - MESOSPHERE_INIT_ABORT_UNLESS(rela_ent == sizeof(Elf::Rela)); + for (size_t i = 0; i < rela_count; i++) { + const auto &rela = *reinterpret_cast(dyn_rela + rela_ent * i); - for (size_t i = 0; i < rela_count; ++i) { - const auto &rela = reinterpret_cast(dyn_rela)[i]; + /* Only allow architecture-specific relocations. */ + while (rela.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } - /* Only allow architecture-specific relocations. */ - while (rela.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } - - /* Apply the relocation. */ - Elf::Addr *target_address = reinterpret_cast(base_address + rela.GetOffset()); - *target_address = base_address + rela.GetAddend(); - } - } - - /* Apply all Relr relocations. */ - if (relr_sz >= sizeof(Elf::Relr)) { - /* Check that the relr relocations are applyable. */ - MESOSPHERE_INIT_ABORT_UNLESS(dyn_relr != 0); - MESOSPHERE_INIT_ABORT_UNLESS(relr_ent == sizeof(Elf::Relr)); - - const size_t relr_count = relr_sz / sizeof(Elf::Relr); - - Elf::Addr *where = nullptr; - for (size_t i = 0; i < relr_count; ++i) { - const auto &relr = reinterpret_cast(dyn_relr)[i]; - - if (relr.IsLocation()) { - /* Update location. */ - where = reinterpret_cast(base_address + relr.GetLocation()); - - /* Apply the relocation. */ - *(where++) += base_address; - } else { - /* Get the bitmap. */ - u64 bitmap = relr.GetBitmap(); - - /* Apply all relocations. */ - while (bitmap != 0) { - const u64 next = util::CountTrailingZeros(bitmap); - bitmap &= ~(static_cast(1) << next); - where[next] += base_address; - } - - /* Advance. */ - where += BITSIZEOF(bitmap) - 1; - } - } + /* Apply the relocation. */ + Elf::Addr *target_address = reinterpret_cast(base_address + rela.GetOffset()); + *target_address = base_address + rela.GetAddend(); } } diff --git a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp index b82e78f84..1d76900ee 100644 --- a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp +++ b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp @@ -171,9 +171,6 @@ namespace ams::kern::init { const KMemoryRegion &slab_region = KMemoryLayout::GetSlabRegion(); KVirtualAddress address = slab_region.GetAddress(); - /* Clear the slab region. */ - std::memset(GetVoidPointer(address), 0, slab_region.GetSize()); - /* Initialize slab type array to be in sorted order. */ KSlabType slab_types[KSlabType_Count]; for (size_t i = 0; i < util::size(slab_types); i++) { slab_types[i] = static_cast(i); } diff --git a/libraries/libmesosphere/source/kern_initial_process.cpp b/libraries/libmesosphere/source/kern_initial_process.cpp index ab38d5774..e435deee4 100644 --- a/libraries/libmesosphere/source/kern_initial_process.cpp +++ b/libraries/libmesosphere/source/kern_initial_process.cpp @@ -27,7 +27,6 @@ namespace ams::kern { constinit KPhysicalAddress g_initial_process_binary_phys_addr = Null; constinit KVirtualAddress g_initial_process_binary_address = Null; - constinit size_t g_initial_process_binary_size = 0; constinit InitialProcessBinaryHeader g_initial_process_binary_header = {}; constinit size_t g_initial_process_secure_memory_size = 0; constinit u64 g_initial_process_id_min = std::numeric_limits::max(); @@ -136,7 +135,7 @@ namespace ams::kern { { /* Allocate the previously unreserved pages. */ KPageGroup unreserve_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer()); - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(unreserve_pg), unreserved_size / PageSize, 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(unreserve_pg), unreserved_size / PageSize, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); /* Add the previously reserved pages. */ if (src_pool == dst_pool && binary_pages != 0) { @@ -156,15 +155,41 @@ namespace ams::kern { KPageGroup *process_pg = std::addressof(pg); ON_SCOPE_EXIT { process_pg->Close(); }; - /* Load the process. */ - reader.Load(pg, data); + /* Get the temporary region. */ + const auto &temp_region = KMemoryLayout::GetTempRegion(); + MESOSPHERE_ABORT_UNLESS(temp_region.GetEndAddress() != 0); - /* If necessary, close/release the aligned part of the data we just loaded. */ - if (const size_t aligned_bin_size = util::AlignDown(binary_size, PageSize); aligned_bin_size != 0 && src_pool != dst_pool) { - Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(data), aligned_bin_size / PageSize); - Kernel::GetSystemResourceLimit().Release(ams::svc::LimitableResource_PhysicalMemoryMax, aligned_bin_size); + /* Map the process's memory into the temporary region. */ + KProcessAddress temp_address = Null; + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().MapPageGroup(std::addressof(temp_address), pg, temp_region.GetAddress(), temp_region.GetSize() / PageSize, KMemoryState_Kernel, KMemoryPermission_KernelReadWrite)); + + /* Setup the new page group's memory, so that we can load the process. */ + { + /* Copy the unaligned ending of the compressed binary. */ + if (const size_t unaligned_size = binary_size - util::AlignDown(binary_size, PageSize); unaligned_size != 0) { + std::memcpy(GetVoidPointer(temp_address + process_size - unaligned_size), GetVoidPointer(data + binary_size - unaligned_size), unaligned_size); + } + + /* Copy the aligned part of the compressed binary. */ + if (const size_t aligned_size = util::AlignDown(binary_size, PageSize); aligned_size != 0 && src_pool == dst_pool) { + std::memmove(GetVoidPointer(temp_address + process_size - binary_size), GetVoidPointer(temp_address), aligned_size); + } else { + if (src_pool != dst_pool) { + std::memcpy(GetVoidPointer(temp_address + process_size - binary_size), GetVoidPointer(data), aligned_size); + Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(data), aligned_size / PageSize); + } + } + + /* Clear the first part of the memory. */ + std::memset(GetVoidPointer(temp_address), 0, process_size - binary_size); } + /* Load the process. */ + MESOSPHERE_R_ABORT_UNLESS(reader.Load(temp_address, params, temp_address + process_size - binary_size)); + + /* Unmap the temporary mapping. */ + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().UnmapPageGroup(temp_address, pg, KMemoryState_Kernel)); + /* Create a KProcess object. */ new_process = KProcess::Create(); MESOSPHERE_ABORT_UNLESS(new_process != nullptr); @@ -173,7 +198,7 @@ namespace ams::kern { /* If the pool is the same, we need to use the workaround page group. */ if (src_pool == dst_pool) { /* Allocate a new, usable group for the process. */ - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(workaround_pg), static_cast(params.code_num_pages), 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(workaround_pg), static_cast(params.code_num_pages), KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); /* Copy data from the working page group to the usable one. */ auto work_it = pg.begin(); @@ -216,6 +241,11 @@ namespace ams::kern { MESOSPHERE_R_ABORT_UNLESS(new_process->Initialize(params, *process_pg, reader.GetCapabilities(), reader.GetNumCapabilities(), std::addressof(Kernel::GetSystemResourceLimit()), dst_pool, reader.IsImmortal())); } + /* Release the memory that was previously reserved. */ + if (const size_t aligned_bin_size = util::AlignDown(binary_size, PageSize); aligned_bin_size != 0 && src_pool != dst_pool) { + Kernel::GetSystemResourceLimit().Release(ams::svc::LimitableResource_PhysicalMemoryMax, aligned_bin_size); + } + /* Set the process's memory permissions. */ MESOSPHERE_R_ABORT_UNLESS(reader.SetMemoryPermissions(new_process->GetPageTable(), params)); @@ -245,11 +275,10 @@ namespace ams::kern { } - void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size) { + void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr) { MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr == Null); g_initial_process_binary_phys_addr = phys_addr; - g_initial_process_binary_size = size; } KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() { @@ -258,12 +287,6 @@ namespace ams::kern { return g_initial_process_binary_phys_addr; } - size_t GetInitialProcessBinarySize() { - MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null); - - return g_initial_process_binary_size; - } - u64 GetInitialProcessIdMin() { return g_initial_process_id_min; } @@ -282,18 +305,15 @@ namespace ams::kern { LoadInitialProcessBinaryHeader(); if (g_initial_process_binary_header.num_processes > 0) { - /* Ensure that we have a non-zero size. */ - const size_t expected_size = g_initial_process_binary_size; - MESOSPHERE_INIT_ABORT_UNLESS(expected_size != 0); - - /* Ensure that the size we need to reserve is as we expect it to be. */ - const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize); - MESOSPHERE_ABORT_UNLESS(total_size == expected_size); - MESOSPHERE_ABORT_UNLESS(total_size <= InitialProcessBinarySizeMax); - /* Reserve pages for the initial process binary from the system resource limit. */ + const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize); MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size)); + /* The initial process binary is potentially over-allocated, so free any extra pages. */ + if (total_size < InitialProcessBinarySizeMax) { + Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(g_initial_process_binary_address + total_size), (InitialProcessBinarySizeMax - total_size) / PageSize); + } + return total_size; } else { return 0; diff --git a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp index 66c0c1645..c084c9053 100644 --- a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp +++ b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp @@ -23,10 +23,6 @@ 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; */ @@ -283,51 +279,4 @@ 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 3aa24c5de..ef585eba8 100644 --- a/libraries/libmesosphere/source/kern_k_address_space_info.cpp +++ b/libraries/libmesosphere/source/kern_k_address_space_info.cpp @@ -37,24 +37,6 @@ 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) { @@ -66,39 +48,12 @@ namespace ams::kern { } - 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(); + uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) { + return GetAddressSpaceInfo(width, type).GetAddress(); } - 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; + size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) { + return GetAddressSpaceInfo(width, type).GetSize(); } 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 ba0359262..6b2c6f4b4 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -184,11 +184,6 @@ namespace ams::kern { case RegionType::NoMapping: break; case RegionType::KernelTraceBuffer: - /* NOTE: This does not match official, but is used to make pre-processing hbl capabilities in userland unnecessary. */ - /* If ktrace isn't enabled, allow ktrace to succeed without mapping anything. */ - if constexpr (!ams::kern::IsKTraceEnabled) { - break; - } case RegionType::OnMemoryBootImage: case RegionType::DTB: R_TRY(f(MemoryRegions[static_cast(type)], perm)); @@ -262,14 +257,7 @@ 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_client_port.cpp b/libraries/libmesosphere/source/kern_k_client_port.cpp index 71ca3d7dd..11977334f 100644 --- a/libraries/libmesosphere/source/kern_k_client_port.cpp +++ b/libraries/libmesosphere/source/kern_k_client_port.cpp @@ -107,6 +107,7 @@ namespace ams::kern { R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions()); new_sessions = cur_sessions + 1; } while (!m_num_sessions.CompareExchangeWeak(cur_sessions, new_sessions)); + } /* Atomically update the peak session tracking. */ @@ -181,6 +182,7 @@ namespace ams::kern { R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions()); new_sessions = cur_sessions + 1; } while (!m_num_sessions.CompareExchangeWeak(cur_sessions, new_sessions)); + } /* Atomically update the peak session tracking. */ diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index 635673cd2..3388e1ce3 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -27,8 +27,7 @@ namespace ams::kern { void KDebugBase::Initialize() { /* Clear the continue flags. */ - m_continue_flags = 0; - m_is_force_debug_prod = GetCurrentProcess().CanForceDebugProd(); + m_continue_flags = 0; } bool KDebugBase::Is64Bit() const { @@ -119,15 +118,12 @@ namespace ams::kern { const size_t cur_size = std::min(remaining, info.GetEndAddress() - GetInteger(cur_address)); /* Read the memory. */ - if (info.GetSvcState() != ams::svc::MemoryState_Io) { + if (info.GetState() != KMemoryState_Io) { /* The memory is normal memory. */ - R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size, this->IsForceDebugProd())); + R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size)); } 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())); + R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size)); } /* Advance. */ @@ -185,12 +181,12 @@ namespace ams::kern { const size_t cur_size = std::min(remaining, info.GetEndAddress() - GetInteger(cur_address)); /* Read the memory. */ - if (info.GetSvcState() != ams::svc::MemoryState_Io) { + if (info.GetState() != KMemoryState_Io) { /* The memory is normal memory. */ R_TRY(target_pt.WriteDebugMemory(cur_address, GetVoidPointer(buffer), cur_size)); } else { /* The memory is IO memory. */ - R_TRY(target_pt.WriteDebugIoMemory(cur_address, GetVoidPointer(buffer), cur_size, info.GetState())); + R_TRY(target_pt.WriteDebugIoMemory(cur_address, GetVoidPointer(buffer), cur_size)); } /* Advance. */ @@ -273,9 +269,6 @@ 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: @@ -415,6 +408,69 @@ 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(); @@ -906,12 +962,7 @@ namespace ams::kern { case ams::svc::DebugException_UndefinedInstruction: { MESOSPHERE_ASSERT(info->info.exception.exception_data_count == 1); - /* 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]; - } + 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 5d9164efb..ff5f21a61 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -73,98 +73,6 @@ namespace ams::kern { } } - NOINLINE void LoadInitialProcessSegment(const KPageGroup &pg, size_t seg_offset, size_t seg_size, size_t binary_size, KVirtualAddress data, bool compressed) { - /* Save the original binary extents, for later use. */ - const KPhysicalAddress binary_phys = KMemoryLayout::GetLinearPhysicalAddress(data); - - /* Create a page group representing the segment. */ - KPageGroup segment_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer()); - MESOSPHERE_R_ABORT_UNLESS(pg.CopyRangeTo(segment_pg, seg_offset, util::AlignUp(seg_size, PageSize))); - - /* Setup the new page group's memory so that we can load the segment. */ - { - KVirtualAddress last_block = Null; - KVirtualAddress last_data = Null; - size_t last_copy_size = 0; - size_t last_clear_size = 0; - size_t remaining_copy_size = binary_size; - for (const auto &block : segment_pg) { - /* Get the current block extents. */ - const auto block_addr = block.GetAddress(); - const size_t block_size = block.GetSize(); - if (remaining_copy_size > 0) { - /* Determine if we need to copy anything. */ - const size_t cur_size = std::min(block_size, remaining_copy_size); - - /* NOTE: The first block may potentially overlap the binary we want to copy to. */ - /* Consider e.g. the case where the overall compressed image has size 0x40000, seg_offset is 0x30000, and binary_size is > 0x20000. */ - /* Suppose too that data points, say, 0x18000 into the compressed image. */ - /* Suppose finally that we simply naively copy in order. */ - /* The first iteration of this loop will perform an 0x10000 copy from image+0x18000 to image + 0x30000 (as there is no overlap). */ - /* The second iteration will perform a copy from image+0x28000 to . */ - /* However, the first copy will have trashed the data in the second copy. */ - /* Thus, we must copy the first block after-the-fact to avoid potentially trashing data in the overlap case. */ - /* It is guaranteed by pre-condition that only the very first block can overlap with the physical binary, so we can simply memmove it at the end. */ - if (last_block != Null) { - /* This is guaranteed by pre-condition, but for ease of debugging, check for no overlap. */ - MESOSPHERE_ASSERT(!util::HasOverlap(GetInteger(binary_phys), binary_size, GetInteger(block_addr), cur_size)); - MESOSPHERE_UNUSED(binary_phys); - - /* We need to copy. */ - std::memcpy(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr)), GetVoidPointer(data), cur_size); - - /* If we need to, clear past where we're copying. */ - if (cur_size != block_size) { - std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr + cur_size)), 0, block_size - cur_size); - } - - /* Advance. */ - remaining_copy_size -= cur_size; - data += cur_size; - } else { - /* Save the first block, which may potentially overlap, so that we can copy it later. */ - last_block = KMemoryLayout::GetLinearVirtualAddress(block_addr); - last_data = data; - last_copy_size = cur_size; - last_clear_size = block_size - cur_size; - - /* Advance. */ - remaining_copy_size -= cur_size; - data += cur_size; - } - } else { - /* We don't have data to copy, so we should just clear the pages. */ - std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr)), 0, block_size); - } - } - - /* Handle a last block. */ - if (last_copy_size != 0) { - if (last_block != last_data) { - std::memmove(GetVoidPointer(last_block), GetVoidPointer(last_data), last_copy_size); - } - if (last_clear_size != 0) { - std::memset(GetVoidPointer(last_block + last_copy_size), 0, last_clear_size); - } - } - } - - /* If compressed, uncompress the data. */ - if (compressed) { - /* Get the temporary region. */ - const auto &temp_region = KMemoryLayout::GetTempRegion(); - MESOSPHERE_ABORT_UNLESS(temp_region.GetEndAddress() != 0); - - /* Map the process's memory into the temporary region. */ - KProcessAddress temp_address = Null; - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().MapPageGroup(std::addressof(temp_address), segment_pg, temp_region.GetAddress(), temp_region.GetSize() / PageSize, KMemoryState_Kernel, KMemoryPermission_KernelReadWrite)); - ON_SCOPE_EXIT { MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().UnmapPageGroup(temp_address, segment_pg, KMemoryState_Kernel)); }; - - /* Uncompress the data. */ - BlzUncompress(GetVoidPointer(temp_address + binary_size)); - } - } - } Result KInitialProcessReader::MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const { @@ -193,25 +101,35 @@ 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 = 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; + out->code_address = map_start + start_address; + 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; + 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; @@ -221,83 +139,49 @@ 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(); } - void KInitialProcessReader::Load(const KPageGroup &pg, KVirtualAddress data) const { + Result KInitialProcessReader::Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms, KProcessAddress src) const { /* Prepare to layout the data. */ - const KVirtualAddress rx_data = data; - const KVirtualAddress ro_data = rx_data + m_kip_header.GetRxCompressedSize(); - const KVirtualAddress rw_data = ro_data + m_kip_header.GetRoCompressedSize(); - const size_t rx_size = m_kip_header.GetRxSize(); - const size_t ro_size = m_kip_header.GetRoSize(); - const size_t rw_size = m_kip_header.GetRwSize(); + const KProcessAddress rx_address = address + m_kip_header.GetRxAddress(); + const KProcessAddress ro_address = address + m_kip_header.GetRoAddress(); + const KProcessAddress rw_address = address + m_kip_header.GetRwAddress(); + const u8 *rx_binary = GetPointer(src); + const u8 *ro_binary = rx_binary + m_kip_header.GetRxCompressedSize(); + const u8 *rw_binary = ro_binary + m_kip_header.GetRoCompressedSize(); - /* If necessary, setup bss. */ - if (const size_t bss_size = m_kip_header.GetBssSize(); bss_size > 0) { - /* Determine how many additional pages are needed for bss. */ - const u64 rw_end = util::AlignUp(m_kip_header.GetRwAddress() + m_kip_header.GetRwSize(), PageSize); - const u64 bss_end = util::AlignUp(m_kip_header.GetBssAddress() + m_kip_header.GetBssSize(), PageSize); - if (rw_end != bss_end) { - /* Find the pages corresponding to bss. */ - size_t cur_offset = 0; - size_t remaining_size = bss_end - rw_end; - size_t bss_offset = rw_end - m_kip_header.GetRxAddress(); - for (auto it = pg.begin(); it != pg.end() && remaining_size > 0; ++it) { - /* Get the current size. */ - const size_t cur_size = it->GetSize(); - - /* Determine if the offset is in range. */ - const size_t rel_diff = bss_offset - cur_offset; - const bool is_before = cur_offset <= bss_offset; - cur_offset += cur_size; - if (is_before && bss_offset < cur_offset) { - /* It is, so clear the bss range. */ - const size_t block_size = std::min(cur_size - rel_diff, remaining_size); - std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(it->GetAddress() + rel_diff)), 0, block_size); - - /* Advance. */ - cur_offset = bss_offset + block_size; - remaining_size -= block_size; - bss_offset += block_size; - } - } + /* Copy text. */ + if (util::AlignUp(m_kip_header.GetRxSize(), PageSize)) { + std::memmove(GetVoidPointer(rx_address), rx_binary, m_kip_header.GetRxCompressedSize()); + if (m_kip_header.IsRxCompressed()) { + BlzUncompress(GetVoidPointer(rx_address + m_kip_header.GetRxCompressedSize())); } } - /* Load .rwdata. */ - LoadInitialProcessSegment(pg, m_kip_header.GetRwAddress() - m_kip_header.GetRxAddress(), rw_size, m_kip_header.GetRwCompressedSize(), rw_data, m_kip_header.IsRwCompressed()); + /* Copy rodata. */ + if (util::AlignUp(m_kip_header.GetRoSize(), PageSize)) { + std::memmove(GetVoidPointer(ro_address), ro_binary, m_kip_header.GetRoCompressedSize()); + if (m_kip_header.IsRoCompressed()) { + BlzUncompress(GetVoidPointer(ro_address + m_kip_header.GetRoCompressedSize())); + } + } - /* Load .rodata. */ - LoadInitialProcessSegment(pg, m_kip_header.GetRoAddress() - m_kip_header.GetRxAddress(), ro_size, m_kip_header.GetRoCompressedSize(), ro_data, m_kip_header.IsRoCompressed()); + /* Copy rwdata. */ + if (util::AlignUp(m_kip_header.GetRwSize(), PageSize)) { + std::memmove(GetVoidPointer(rw_address), rw_binary, m_kip_header.GetRwCompressedSize()); + if (m_kip_header.IsRwCompressed()) { + BlzUncompress(GetVoidPointer(rw_address + m_kip_header.GetRwCompressedSize())); + } + } - /* Load .text. */ - LoadInitialProcessSegment(pg, m_kip_header.GetRxAddress() - m_kip_header.GetRxAddress(), rx_size, m_kip_header.GetRxCompressedSize(), rx_data, m_kip_header.IsRxCompressed()); + MESOSPHERE_UNUSED(params); + + R_SUCCEED(); } Result KInitialProcessReader::SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter ¶ms) const { diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 639c047d3..0a5732032 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -21,8 +21,7 @@ namespace ams::kern { constexpr const std::pair MemoryStateNames[] = { {KMemoryState_Free , "----- Free -----"}, - {KMemoryState_IoMemory , "IoMemory "}, - {KMemoryState_IoRegister , "IoRegister "}, + {KMemoryState_Io , "Io "}, {KMemoryState_Static , "Static "}, {KMemoryState_Code , "Code "}, {KMemoryState_CodeData , "CodeData "}, @@ -54,11 +53,11 @@ namespace ams::kern { return "Unknown "; } - constexpr const char *GetMemoryPermissionString(const KMemoryBlock &block) { - if (block.GetState() == KMemoryState_Free) { + constexpr const char *GetMemoryPermissionString(const KMemoryInfo &info) { + if (info.m_state == KMemoryState_Free) { return " "; } else { - switch (block.GetPermission()) { + switch (info.m_permission) { case KMemoryPermission_UserReadExecute: return "r-x"; case KMemoryPermission_UserRead: @@ -71,19 +70,19 @@ namespace ams::kern { } } - 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; + 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; - 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' : '-'; + 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' : '-'; - 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()); + 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); } } @@ -118,78 +117,30 @@ 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 { - /* 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()) { + 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()) { break; } - - /* We only want to consider free blocks. */ - if (it->GetState() != KMemoryState_Free) { + if (info.m_state != KMemoryState_Free) { continue; } - /* 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; - } + KProcessAddress area = (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress(); + area += guard_pages * PageSize; - /* Try the suggested candidate (coercing into the search region if needed). */ - KProcessAddress candidate = candidate_start; - if (candidate < search_start) { - candidate = search_start; - } + const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset; + area = (area <= offset_area) ? offset_area : offset_area + alignment; - /* Check if the candidate is valid. */ - if (candidate <= search_end && candidate <= candidate_end) { - return candidate; + 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; } } } @@ -219,7 +170,7 @@ namespace ams::kern { it = prev; } - if (address + num_pages * PageSize < it->GetEndAddress()) { + if (address + num_pages * PageSize < it->GetMemoryInfo().GetEndAddress()) { break; } } @@ -237,39 +188,43 @@ 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 < it->GetEndAddress()) { + if (cur_address + remaining_size < cur_info.GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; - cur_address = it->GetEndAddress(); + remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; + cur_address = cur_info.GetEndAddress(); } } else { /* If we need to, create a new block before and insert it. */ - if (it->GetAddress() != GetInteger(cur_address)) { + if (cur_info.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_address = it->GetAddress(); + cur_info = it->GetMemoryInfo(); + cur_address = cur_info.GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (it->GetSize() > remaining_size) { + if (cur_info.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 += it->GetSize(); - remaining_pages -= it->GetNumPages(); + it->Update(state, perm, attr, cur_address == address, set_disable_attr, clear_disable_attr); + cur_address += cur_info.GetSize(); + remaining_pages -= cur_info.GetNumPages(); } it++; } @@ -277,7 +232,7 @@ namespace ams::kern { this->CoalesceForUpdate(allocator, address, num_pages); } - void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr) { + void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr) { /* Ensure for auditing that we never end up with an invalid tree. */ KScopedMemoryBlockManagerAuditor auditor(this); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(address), PageSize)); @@ -289,38 +244,42 @@ 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 (it->GetAddress() != GetInteger(cur_address)) { + if (cur_info.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_address = it->GetAddress(); + cur_info = it->GetMemoryInfo(); + cur_address = cur_info.GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (it->GetSize() > remaining_size) { + if (cur_info.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 += it->GetSize(); - remaining_pages -= it->GetNumPages(); + it->Update(state, perm, attr, false, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + cur_address += cur_info.GetSize(); + remaining_pages -= cur_info.GetNumPages(); } else { /* If we already have the right properties, just advance. */ - if (cur_address + remaining_size < it->GetEndAddress()) { + if (cur_address + remaining_size < cur_info.GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; - cur_address = it->GetEndAddress(); + remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; + cur_address = cur_info.GetEndAddress(); } } it++; @@ -342,82 +301,34 @@ 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 (it->GetAddress() != cur_address) { + if (cur_info.m_address != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_address = it->GetAddress(); + cur_info = it->GetMemoryInfo(); + cur_address = cur_info.GetAddress(); } - if (it->GetSize() > remaining_size) { + if (cur_info.GetSize() > remaining_size) { /* If we need to, create a new block after and insert it. */ KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); + + cur_info = it->GetMemoryInfo(); } /* Call the locked update function. */ - (std::addressof(*it)->*lock_func)(perm, it->GetAddress() == address, it->GetEndAddress() == end_address); - cur_address += it->GetSize(); - remaining_pages -= it->GetNumPages(); - it++; - } - - this->CoalesceForUpdate(allocator, address, num_pages); - } - - void KMemoryBlockManager::UpdateAttribute(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, u32 mask, u32 attr) { - /* Ensure for auditing that we never end up with an invalid tree. */ - KScopedMemoryBlockManagerAuditor auditor(this); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(address), PageSize)); - - KProcessAddress cur_address = address; - size_t remaining_pages = num_pages; - iterator it = this->FindIterator(address); - - while (remaining_pages > 0) { - const size_t remaining_size = remaining_pages * PageSize; - - if ((it->GetAttribute() & mask) != attr) { - /* If we need to, create a new block before and insert it. */ - 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_address = it->GetAddress(); - } - - /* If we need to, create a new block after and insert it. */ - 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); - } - - /* Update block state. */ - it->UpdateAttribute(mask, attr); - cur_address += it->GetSize(); - remaining_pages -= it->GetNumPages(); - } else { - /* If we already have the right attributes, just advance. */ - if (cur_address + remaining_size < it->GetEndAddress()) { - remaining_pages = 0; - cur_address += remaining_size; - } else { - remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; - cur_address = it->GetEndAddress(); - } - } + (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(); it++; } @@ -433,6 +344,8 @@ 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)) { @@ -440,17 +353,17 @@ namespace ams::kern { } /* Sequential blocks should be sequential. */ - if (prev->GetEndAddress() != it->GetAddress()) { + if (prev_info.GetEndAddress() != cur_info.GetAddress()) { return false; } /* If the block is ipc locked, it must have a count. */ - if ((it->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && it->GetIpcLockCount() == 0) { + if ((cur_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && cur_info.m_ipc_lock_count == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((it->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && it->GetDeviceUseCount() == 0) { + if ((cur_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && cur_info.m_device_use_count == 0) { return false; } @@ -460,13 +373,14 @@ 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->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && prev->GetIpcLockCount() == 0) { + if ((prev_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && prev_info.m_ipc_lock_count == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((prev->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && prev->GetDeviceUseCount() == 0) { + if ((prev_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && prev_info.m_device_use_count == 0) { return false; } } @@ -479,7 +393,7 @@ namespace ams::kern { void KMemoryBlockManager::DumpBlocks() const { /* Dump each block. */ for (const auto &block : m_memory_block_tree) { - DumpMemoryBlock(block); + DumpMemoryInfo(block.GetMemoryInfo()); } } } diff --git a/libraries/libmesosphere/source/kern_k_memory_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_manager.cpp index aa5f5bdcc..b9999be81 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, const u32 *min_align_shifts) { + void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) { /* 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); @@ -108,8 +108,7 @@ namespace ams::kern { /* Free each region to its corresponding heap. */ size_t reserved_sizes[MaxManagerCount] = {}; const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress(); - const size_t ini_size = GetInitialProcessBinarySize(); - const KPhysicalAddress ini_end = ini_start + ini_size; + const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax; const KPhysicalAddress ini_last = ini_end - 1; for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) { if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) { @@ -127,13 +126,13 @@ namespace ams::kern { } /* Open/reserve the ini memory. */ - manager.OpenFirst(ini_start, ini_size / PageSize); - reserved_sizes[it.GetAttributes()] += ini_size; + manager.OpenFirst(ini_start, InitialProcessBinarySizeMax / PageSize); + reserved_sizes[it.GetAttributes()] += InitialProcessBinarySizeMax; /* Free memory after the ini to the heap. */ if (ini_last != cur_last) { MESOSPHERE_ABORT_UNLESS(cur_end != Null); - manager.Free(ini_end, (cur_end - ini_end) / PageSize); + manager.Free(ini_end, cur_end - ini_end); } } else { /* Ensure there's no partial overlap with the ini image. */ @@ -154,17 +153,6 @@ 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) { @@ -203,19 +191,8 @@ namespace ams::kern { return Null; } - /* 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. */ + const auto [pool, dir] = DecodeOption(option); KScopedLightLock lk(m_pool_locks[pool]); /* Choose a heap based on our page size request. */ @@ -247,14 +224,7 @@ namespace ams::kern { return allocated_block; } - 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]); - + Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random) { /* Choose a heap based on our page size request. */ const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory()); @@ -270,7 +240,7 @@ namespace ams::kern { }; /* Keep allocating until we've allocated all our pages. */ - for (s32 index = heap_index; index >= min_heap_index && num_pages > 0; index--) { + for (s32 index = heap_index; index >= 0 && num_pages > 0; index--) { const size_t pages_per_alloc = KPageHeap::GetBlockNumPages(index); for (Impl *cur_manager = this->GetFirstManager(pool, dir); cur_manager != nullptr; cur_manager = this->GetNextManager(cur_manager, dir)) { while (num_pages >= pages_per_alloc) { @@ -303,7 +273,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_pages, u32 option) { + Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option) { MESOSPHERE_ASSERT(out != nullptr); MESOSPHERE_ASSERT(out->GetNumPages() == 0); @@ -314,11 +284,8 @@ namespace ams::kern { const auto [pool, dir] = DecodeOption(option); KScopedLightLock lk(m_pool_locks[pool]); - /* Choose a heap based on our alignment size request. */ - const s32 heap_index = KPageHeap::GetAlignedBlockIndex(align_pages, align_pages); - /* Allocate the page group. */ - R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, m_has_optimized_process[pool], true, heap_index)); + R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, m_has_optimized_process[pool], true)); /* Open the first reference to the pages. */ for (const auto &block : *out) { @@ -358,11 +325,8 @@ namespace ams::kern { const bool has_optimized = m_has_optimized_process[pool]; const bool is_optimized = m_optimized_process_ids[pool] == process_id; - /* Always use the minimum alignment size. */ - const s32 heap_index = 0; - /* Allocate the page group. */ - R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, false, heap_index)); + R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, false)); /* Set whether we should optimize. */ optimized = has_optimized && is_optimized; diff --git a/libraries/libmesosphere/source/kern_k_page_group.cpp b/libraries/libmesosphere/source/kern_k_page_group.cpp index a51e0a1ff..af363240f 100644 --- a/libraries/libmesosphere/source/kern_k_page_group.cpp +++ b/libraries/libmesosphere/source/kern_k_page_group.cpp @@ -84,58 +84,6 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageGroup::CopyRangeTo(KPageGroup &out, size_t range_offset, size_t range_size) const { - /* Get the previous last block for the group. */ - KBlockInfo * const out_last = out.m_last_block; - const auto out_last_addr = out_last != nullptr ? out_last->GetAddress() : Null; - const auto out_last_np = out_last != nullptr ? out_last->GetNumPages() : 0; - - /* Ensure we cleanup the group on failure. */ - ON_RESULT_FAILURE { - KBlockInfo *cur = out_last != nullptr ? out_last->GetNext() : out.m_first_block; - while (cur != nullptr) { - KBlockInfo *next = cur->GetNext(); - out.m_manager->Free(cur); - cur = next; - } - - if (out_last != nullptr) { - out_last->Initialize(out_last_addr, out_last_np); - out_last->SetNext(nullptr); - } else { - out.m_first_block = nullptr; - } - out.m_last_block = out_last; - }; - - /* Find the pages within the requested range. */ - size_t cur_offset = 0, remaining_size = range_size; - for (auto it = this->begin(); it != this->end() && remaining_size > 0; ++it) { - /* Get the current size. */ - const size_t cur_size = it->GetSize(); - - /* Determine if the offset is in range. */ - const size_t rel_diff = range_offset - cur_offset; - const bool is_before = cur_offset <= range_offset; - cur_offset += cur_size; - if (is_before && range_offset < cur_offset) { - /* It is, so add the block. */ - const size_t block_size = std::min(cur_size - rel_diff, remaining_size); - R_TRY(out.AddBlock(it->GetAddress() + rel_diff, block_size / PageSize)); - - /* Advance. */ - cur_offset = range_offset + block_size; - remaining_size -= block_size; - range_offset += block_size; - } - } - - /* Check that we successfully copied the range. */ - MESOSPHERE_ABORT_UNLESS(remaining_size == 0); - - R_SUCCEED(); - } - void KPageGroup::Open() const { auto &mm = Kernel::GetMemoryManager(); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index ad42a62a4..06aa158c6 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -97,12 +97,15 @@ namespace ams::kern { m_enable_aslr = true; m_enable_device_address_space_merge = false; - for (auto i = 0; i < RegionType_Count; ++i) { - m_region_starts[i] = 0; - m_region_ends[i] = 0; - } - + m_heap_region_start = 0; + m_heap_region_end = 0; m_current_heap_end = 0; + m_alias_region_start = 0; + m_alias_region_end = 0; + m_stack_region_start = 0; + m_stack_region_end = 0; + m_kernel_map_region_start = 0; + m_kernel_map_region_end = 0; m_alias_code_region_start = 0; m_alias_code_region_end = 0; m_code_region_start = 0; @@ -112,7 +115,6 @@ namespace ams::kern { m_mapped_unsafe_physical_memory = 0; m_mapped_insecure_memory = 0; m_mapped_ipc_server_memory = 0; - m_alias_region_extra_size = 0; m_memory_block_slab_manager = Kernel::GetSystemSystemResource().GetMemoryBlockSlabManagerPointer(); m_block_info_manager = Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer(); @@ -133,7 +135,7 @@ namespace ams::kern { R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager)); } - Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { /* Validate the region. */ MESOSPHERE_ABORT_UNLESS(start <= code_address); MESOSPHERE_ABORT_UNLESS(code_address < code_address + code_size); @@ -141,76 +143,57 @@ namespace ams::kern { /* Define helpers. */ auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceStart(flags, type, code_size); + return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); }; auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceSize(flags, type); + return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); }; - /* Default to zero alias region extra size. */ - m_alias_region_extra_size = 0; - /* Set our width and heap/alias sizes. */ - m_address_space_width = GetAddressSpaceWidth(flags); + m_address_space_width = GetAddressSpaceWidth(as_type); 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 ((as_type & 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; size_t stack_region_size; size_t kernel_map_region_size; - KProcessAddress before_process_code_start, after_process_code_start; - size_t before_process_code_size, after_process_code_size; if (m_address_space_width == 39) { - stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Stack); - kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); - - m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_Map39Bit); - m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_Map39Bit); - m_alias_code_region_start = m_code_region_start; - m_alias_code_region_end = m_code_region_end; - - process_code_start = util::AlignDown(GetInteger(code_address), RegionAlignment); - process_code_end = util::AlignUp(GetInteger(code_address) + code_size, RegionAlignment); - - before_process_code_start = m_code_region_start; - before_process_code_size = process_code_start - before_process_code_start; - after_process_code_start = process_code_end; - after_process_code_size = m_code_region_end - process_code_end; - - /* If we have a 39-bit address space and should, enable extra size to the alias region. */ - if (flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { - /* Extra size is 1/8th of the address space. */ - m_alias_region_extra_size = (static_cast(1) << m_address_space_width) / 8; - - alias_region_size += m_alias_region_extra_size; - } + alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); + heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); + stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Stack); + kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); + m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_Map39Bit); + m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_Map39Bit); + m_alias_code_region_start = m_code_region_start; + m_alias_code_region_end = m_code_region_end; + process_code_start = util::AlignDown(GetInteger(code_address), RegionAlignment); + process_code_end = util::AlignUp(GetInteger(code_address) + code_size, RegionAlignment); } else { - stack_region_size = 0; - kernel_map_region_size = 0; - - m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_MapSmall); - m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); - m_alias_code_region_start = m_code_region_start; - m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge) + GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); - m_region_starts[RegionType_Stack] = m_code_region_start; - m_region_ends[RegionType_Stack] = m_code_region_end; - m_region_starts[RegionType_KernelMap] = m_code_region_start; - m_region_ends[RegionType_KernelMap] = m_code_region_end; - - process_code_start = m_code_region_start; - process_code_end = m_code_region_end; - - before_process_code_start = m_code_region_start; - before_process_code_size = 0; - after_process_code_start = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge); - after_process_code_size = GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); + stack_region_size = 0; + kernel_map_region_size = 0; + m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_MapSmall); + m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); + m_stack_region_start = m_code_region_start; + m_alias_code_region_start = m_code_region_start; + m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge) + GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); + m_stack_region_end = m_code_region_end; + m_kernel_map_region_start = m_code_region_start; + m_kernel_map_region_end = m_code_region_end; + process_code_start = m_code_region_start; + process_code_end = m_code_region_end; } /* Set other basic fields. */ - m_enable_aslr = (flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; - m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; + m_enable_aslr = enable_aslr; + m_enable_device_address_space_merge = enable_das_merge; m_address_space_start = start; m_address_space_end = end; m_is_kernel = false; @@ -218,285 +201,100 @@ namespace ams::kern { m_block_info_manager = system_resource->GetBlockInfoManagerPointer(); m_resource_limit = resource_limit; - /* Set up our undetermined regions. */ - { - /* Declare helper structure for layout process. */ - struct RegionLayoutInfo { - size_t size; - RegionType type; - s32 alloc_index; /* 0 for before process code, 1 for after process code */ - }; + /* Determine the region we can place our undetermineds in. */ + KProcessAddress alloc_start; + size_t alloc_size; + if ((GetInteger(process_code_start) - GetInteger(m_code_region_start)) >= (GetInteger(end) - GetInteger(process_code_end))) { + alloc_start = m_code_region_start; + alloc_size = GetInteger(process_code_start) - GetInteger(m_code_region_start); + } else { + alloc_start = process_code_end; + alloc_size = GetInteger(end) - GetInteger(process_code_end); + } + const size_t needed_size = (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size); + R_UNLESS(alloc_size >= needed_size, svc::ResultOutOfMemory()); - /* Create region layout info array, and add regions to it. */ - RegionLayoutInfo region_layouts[RegionType_Count] = {}; - size_t num_regions = 0; + const size_t remaining_size = alloc_size - needed_size; - if (kernel_map_region_size > 0) { region_layouts[num_regions++] = { .size = kernel_map_region_size, .type = RegionType_KernelMap, .alloc_index = 0, }; } - if (stack_region_size > 0) { region_layouts[num_regions++] = { .size = stack_region_size, .type = RegionType_Stack, .alloc_index = 0, }; } + /* Determine random placements for each region. */ + size_t alias_rnd = 0, heap_rnd = 0, stack_rnd = 0, kmap_rnd = 0; + if (enable_aslr) { + alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; + heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; + stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; + kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; + } - region_layouts[num_regions++] = { .size = alias_region_size, .type = RegionType_Alias, .alloc_index = 0, }; - region_layouts[num_regions++] = { .size = heap_region_size, .type = RegionType_Heap, .alloc_index = 0, }; + /* Setup heap and alias regions. */ + m_alias_region_start = alloc_start + alias_rnd; + m_alias_region_end = m_alias_region_start + alias_region_size; + m_heap_region_start = alloc_start + heap_rnd; + m_heap_region_end = m_heap_region_start + heap_region_size; - /* Selection-sort the regions by size largest-to-smallest. */ - for (size_t i = 0; i < num_regions - 1; ++i) { - for (size_t j = i + 1; j < num_regions; ++j) { - if (region_layouts[i].size < region_layouts[j].size) { - std::swap(region_layouts[i], region_layouts[j]); - } - } + if (alias_rnd <= heap_rnd) { + m_heap_region_start += alias_region_size; + m_heap_region_end += alias_region_size; + } else { + m_alias_region_start += heap_region_size; + m_alias_region_end += heap_region_size; + } + + /* Setup stack region. */ + if (stack_region_size) { + m_stack_region_start = alloc_start + stack_rnd; + m_stack_region_end = m_stack_region_start + stack_region_size; + + if (alias_rnd < stack_rnd) { + m_stack_region_start += alias_region_size; + m_stack_region_end += alias_region_size; + } else { + m_alias_region_start += stack_region_size; + m_alias_region_end += stack_region_size; } - /* Layout the regions. */ - constexpr auto AllocIndexCount = 2; - KProcessAddress alloc_starts[AllocIndexCount] = { before_process_code_start, after_process_code_start }; - size_t alloc_sizes[AllocIndexCount] = { before_process_code_size, after_process_code_size }; - size_t alloc_counts[AllocIndexCount] = {}; - for (size_t i = 0; i < num_regions; ++i) { - /* Get reference to the current region. */ - auto &cur_region = region_layouts[i]; + if (heap_rnd < stack_rnd) { + m_stack_region_start += heap_region_size; + m_stack_region_end += heap_region_size; + } else { + m_heap_region_start += stack_region_size; + m_heap_region_end += stack_region_size; + } + } - /* Determine where the current region should go. */ - cur_region.alloc_index = alloc_sizes[1] >= alloc_sizes[0] ? 1 : 0; - ++alloc_counts[cur_region.alloc_index]; + /* Setup kernel map region. */ + if (kernel_map_region_size) { + m_kernel_map_region_start = alloc_start + kmap_rnd; + m_kernel_map_region_end = m_kernel_map_region_start + kernel_map_region_size; - /* Check that the current region can fit. */ - R_UNLESS(alloc_sizes[cur_region.alloc_index] >= cur_region.size, svc::ResultOutOfMemory()); - - /* Update our remaining size tracking. */ - alloc_sizes[cur_region.alloc_index] -= cur_region.size; + if (alias_rnd < kmap_rnd) { + m_kernel_map_region_start += alias_region_size; + m_kernel_map_region_end += alias_region_size; + } else { + m_alias_region_start += kernel_map_region_size; + m_alias_region_end += kernel_map_region_size; } - /* Selection sort the regions to coalesce them by alloc index. */ - for (size_t i = 0; i < num_regions - 1; ++i) { - for (size_t j = i + 1; j < num_regions; ++j) { - if (region_layouts[i].alloc_index > region_layouts[j].alloc_index) { - std::swap(region_layouts[i], region_layouts[j]); - } - } + if (heap_rnd < kmap_rnd) { + m_kernel_map_region_start += heap_region_size; + m_kernel_map_region_end += heap_region_size; + } else { + m_heap_region_start += kernel_map_region_size; + m_heap_region_end += kernel_map_region_size; } - /* Layout the regions for each alloc index. */ - for (auto cur_alloc_index = 0; cur_alloc_index < AllocIndexCount; ++cur_alloc_index) { - /* If there are no regions to place, continue. */ - const size_t cur_alloc_count = alloc_counts[cur_alloc_index]; - if (cur_alloc_count == 0) { - continue; - } - - /* Determine the starting region index for the current alloc index. */ - size_t cur_region_index = 0; - for (size_t i = 0; i < num_regions; ++i) { - if (region_layouts[i].alloc_index == cur_alloc_index) { - cur_region_index = i; - break; - } - } - - /* If aslr is enabled, randomize the current region order. Otherwise, sort by type. */ - if (m_enable_aslr) { - for (size_t i = 0; i < cur_alloc_count - 1; ++i) { - std::swap(region_layouts[cur_region_index + i], region_layouts[cur_region_index + KSystemControl::GenerateRandomRange(i, cur_alloc_count - 1)]); - } + if (stack_region_size) { + if (stack_rnd < kmap_rnd) { + m_kernel_map_region_start += stack_region_size; + m_kernel_map_region_end += stack_region_size; } else { - for (size_t i = 0; i < cur_alloc_count - 1; ++i) { - for (size_t j = i + 1; j < cur_alloc_count; ++j) { - if (region_layouts[cur_region_index + i].type > region_layouts[cur_region_index + j].type) { - std::swap(region_layouts[cur_region_index + i], region_layouts[cur_region_index + j]); - } - } - } - } - - /* Determine aslr offsets for the current space. */ - size_t aslr_offsets[RegionType_Count] = {}; - if (m_enable_aslr) { - /* Generate the aslr offsets. */ - for (size_t i = 0; i < cur_alloc_count; ++i) { - aslr_offsets[i] = KSystemControl::GenerateRandomRange(0, alloc_sizes[cur_alloc_index] / RegionAlignment) * RegionAlignment; - } - - /* Sort the aslr offsets. */ - for (size_t i = 0; i < cur_alloc_count - 1; ++i) { - for (size_t j = i + 1; j < cur_alloc_count; ++j) { - if (aslr_offsets[i] > aslr_offsets[j]) { - std::swap(aslr_offsets[i], aslr_offsets[j]); - } - } - } - } - - /* Calculate final region positions. */ - KProcessAddress prev_region_end = alloc_starts[cur_alloc_index]; - size_t prev_aslr_offset = 0; - for (size_t i = 0; i < cur_alloc_count; ++i) { - /* Get the current region. */ - auto &cur_region = region_layouts[cur_region_index + i]; - - /* Set the current region start/end. */ - m_region_starts[cur_region.type] = (aslr_offsets[i] - prev_aslr_offset) + GetInteger(prev_region_end); - m_region_ends[cur_region.type] = m_region_starts[cur_region.type] + cur_region.size; - - /* Update tracking variables. */ - prev_region_end = m_region_ends[cur_region.type]; - prev_aslr_offset = aslr_offsets[i]; - } - } - - /* Declare helpers to check that regions are inside our address space. */ - const KProcessAddress process_code_last = process_code_end - 1; - auto IsInAddressSpace = [&](KProcessAddress addr) ALWAYS_INLINE_LAMBDA { return m_address_space_start <= addr && addr <= m_address_space_end; }; - - /* Ensure that the KernelMap region is valid. */ - for (size_t k = 0; k < num_regions; ++k) { - if (const auto &kmap_region = region_layouts[k]; kmap_region.type == RegionType_KernelMap) { - /* If there's no kmap region, we have nothing to check. */ - if (kmap_region.size == 0) { - break; - } - - /* Check that the kmap region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_KernelMap])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_KernelMap])); - - /* Check for overlap with process code. */ - const KProcessAddress kmap_start = m_region_starts[RegionType_KernelMap]; - const KProcessAddress kmap_last = m_region_ends[RegionType_KernelMap] - 1; - MESOSPHERE_ABORT_UNLESS(kernel_map_region_size == 0 || kmap_last < process_code_start || process_code_last < kmap_start); - - /* Check for overlap with stack. */ - for (size_t s = 0; s < num_regions; ++s) { - if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { - if (stack_region.size != 0) { - const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; - const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; - MESOSPHERE_ABORT_UNLESS((kernel_map_region_size == 0 && stack_region_size == 0) || kmap_last < stack_start || stack_last < kmap_start); - } - break; - } - } - - /* Check for overlap with alias. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - if (alias_region.size != 0) { - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(kmap_last < alias_start || alias_last < kmap_start); - } - break; - } - } - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(kmap_last < heap_start || heap_last < kmap_start); - } - break; - } - } - } - } - - /* Check that the Stack region is valid. */ - for (size_t s = 0; s < num_regions; ++s) { - if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { - /* If there's no stack region, we have nothing to check. */ - if (stack_region.size == 0) { - break; - } - - /* Check that the stack region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Stack])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Stack])); - - /* Check for overlap with process code. */ - const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; - const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; - MESOSPHERE_ABORT_UNLESS(stack_region_size == 0 || stack_last < process_code_start || process_code_last < stack_start); - - /* Check for overlap with alias. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - if (alias_region.size != 0) { - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(stack_last < alias_start || alias_last < stack_start); - } - break; - } - } - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(stack_last < heap_start || heap_last < stack_start); - } - break; - } - } - } - } - - /* Check that the Alias region is valid. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - /* If there's no alias region, we have nothing to check. */ - if (alias_region.size == 0) { - break; - } - - /* Check that the alias region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Alias])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Alias])); - - /* Check for overlap with process code. */ - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(alias_last < process_code_start || process_code_last < alias_start); - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(alias_last < heap_start || heap_last < alias_start); - } - break; - } - } - } - } - - /* Check that the Heap region is valid. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - /* If there's no heap region, we have nothing to check. */ - if (heap_region.size == 0) { - break; - } - - /* Check that the heap region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Heap])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Heap])); - - /* Check for overlap with process code. */ - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(heap_last < process_code_start || process_code_last < heap_start); + m_stack_region_start += kernel_map_region_size; + m_stack_region_end += kernel_map_region_size; } } } /* Set heap and fill members. */ - m_current_heap_end = m_region_starts[RegionType_Heap]; + m_current_heap_end = m_heap_region_start; m_max_heap_size = 0; m_mapped_physical_memory_size = 0; m_mapped_unsafe_physical_memory = 0; @@ -511,6 +309,32 @@ namespace ams::kern { /* Set allocation option. */ m_allocate_option = KMemoryManager::EncodeOption(pool, from_back ? KMemoryManager::Direction_FromBack : KMemoryManager::Direction_FromFront); + /* Ensure that we regions inside our address space. */ + auto IsInAddressSpace = [&](KProcessAddress addr) ALWAYS_INLINE_LAMBDA { return m_address_space_start <= addr && addr <= m_address_space_end; }; + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_alias_region_start)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_alias_region_end)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_heap_region_start)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_heap_region_end)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_stack_region_start)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_stack_region_end)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_kernel_map_region_start)); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_kernel_map_region_end)); + + /* Ensure that we selected regions that don't overlap. */ + const KProcessAddress alias_start = m_alias_region_start; + const KProcessAddress alias_last = m_alias_region_end - 1; + const KProcessAddress heap_start = m_heap_region_start; + const KProcessAddress heap_last = m_heap_region_end - 1; + const KProcessAddress stack_start = m_stack_region_start; + const KProcessAddress stack_last = m_stack_region_end - 1; + const KProcessAddress kmap_start = m_kernel_map_region_start; + const KProcessAddress kmap_last = m_kernel_map_region_end - 1; + MESOSPHERE_ABORT_UNLESS(alias_last < heap_start || heap_last < alias_start); + MESOSPHERE_ABORT_UNLESS(alias_last < stack_start || stack_last < alias_start); + MESOSPHERE_ABORT_UNLESS(alias_last < kmap_start || kmap_last < alias_start); + MESOSPHERE_ABORT_UNLESS(heap_last < stack_start || stack_last < heap_start); + MESOSPHERE_ABORT_UNLESS(heap_last < kmap_start || kmap_last < heap_start); + /* Initialize our implementation. */ m_impl.InitializeForProcess(table, GetInteger(start), GetInteger(end)); @@ -544,77 +368,77 @@ namespace ams::kern { cpu::InvalidateEntireInstructionCache(); } - KProcessAddress KPageTableBase::GetRegionAddress(ams::svc::MemoryState state) const { + KProcessAddress KPageTableBase::GetRegionAddress(KMemoryState state) const { switch (state) { - case ams::svc::MemoryState_Free: - case ams::svc::MemoryState_Kernel: + case KMemoryState_Free: + case KMemoryState_Kernel: return m_address_space_start; - case ams::svc::MemoryState_Normal: - return m_region_starts[RegionType_Heap]; - case ams::svc::MemoryState_Ipc: - case ams::svc::MemoryState_NonSecureIpc: - case ams::svc::MemoryState_NonDeviceIpc: - return m_region_starts[RegionType_Alias]; - case ams::svc::MemoryState_Stack: - return m_region_starts[RegionType_Stack]; - case ams::svc::MemoryState_Static: - case ams::svc::MemoryState_ThreadLocal: - return m_region_starts[RegionType_KernelMap]; - case ams::svc::MemoryState_Io: - case ams::svc::MemoryState_Shared: - case ams::svc::MemoryState_AliasCode: - case ams::svc::MemoryState_AliasCodeData: - case ams::svc::MemoryState_Transfered: - case ams::svc::MemoryState_SharedTransfered: - case ams::svc::MemoryState_SharedCode: - case ams::svc::MemoryState_GeneratedCode: - case ams::svc::MemoryState_CodeOut: - case ams::svc::MemoryState_Coverage: - case ams::svc::MemoryState_Insecure: + case KMemoryState_Normal: + return m_heap_region_start; + case KMemoryState_Ipc: + case KMemoryState_NonSecureIpc: + case KMemoryState_NonDeviceIpc: + return m_alias_region_start; + case KMemoryState_Stack: + return m_stack_region_start; + case KMemoryState_Static: + case KMemoryState_ThreadLocal: + return m_kernel_map_region_start; + case KMemoryState_Io: + case KMemoryState_Shared: + case KMemoryState_AliasCode: + case KMemoryState_AliasCodeData: + case KMemoryState_Transfered: + case KMemoryState_SharedTransfered: + case KMemoryState_SharedCode: + case KMemoryState_GeneratedCode: + case KMemoryState_CodeOut: + case KMemoryState_Coverage: + case KMemoryState_Insecure: return m_alias_code_region_start; - case ams::svc::MemoryState_Code: - case ams::svc::MemoryState_CodeData: + case KMemoryState_Code: + case KMemoryState_CodeData: return m_code_region_start; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } - size_t KPageTableBase::GetRegionSize(ams::svc::MemoryState state) const { + size_t KPageTableBase::GetRegionSize(KMemoryState state) const { switch (state) { - case ams::svc::MemoryState_Free: - case ams::svc::MemoryState_Kernel: + case KMemoryState_Free: + case KMemoryState_Kernel: return m_address_space_end - m_address_space_start; - case ams::svc::MemoryState_Normal: - return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; - case ams::svc::MemoryState_Ipc: - case ams::svc::MemoryState_NonSecureIpc: - case ams::svc::MemoryState_NonDeviceIpc: - return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; - case ams::svc::MemoryState_Stack: - return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; - case ams::svc::MemoryState_Static: - case ams::svc::MemoryState_ThreadLocal: - return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; - case ams::svc::MemoryState_Io: - case ams::svc::MemoryState_Shared: - case ams::svc::MemoryState_AliasCode: - case ams::svc::MemoryState_AliasCodeData: - case ams::svc::MemoryState_Transfered: - case ams::svc::MemoryState_SharedTransfered: - case ams::svc::MemoryState_SharedCode: - case ams::svc::MemoryState_GeneratedCode: - case ams::svc::MemoryState_CodeOut: - case ams::svc::MemoryState_Coverage: - case ams::svc::MemoryState_Insecure: + case KMemoryState_Normal: + return m_heap_region_end - m_heap_region_start; + case KMemoryState_Ipc: + case KMemoryState_NonSecureIpc: + case KMemoryState_NonDeviceIpc: + return m_alias_region_end - m_alias_region_start; + case KMemoryState_Stack: + return m_stack_region_end - m_stack_region_start; + case KMemoryState_Static: + case KMemoryState_ThreadLocal: + return m_kernel_map_region_end - m_kernel_map_region_start; + case KMemoryState_Io: + case KMemoryState_Shared: + case KMemoryState_AliasCode: + case KMemoryState_AliasCodeData: + case KMemoryState_Transfered: + case KMemoryState_SharedTransfered: + case KMemoryState_SharedCode: + case KMemoryState_GeneratedCode: + case KMemoryState_CodeOut: + case KMemoryState_Coverage: + case KMemoryState_Insecure: return m_alias_code_region_end - m_alias_code_region_start; - case ams::svc::MemoryState_Code: - case ams::svc::MemoryState_CodeData: + case KMemoryState_Code: + case KMemoryState_CodeData: return m_code_region_end - m_code_region_start; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } - bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { + bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { const KProcessAddress end = addr + size; const KProcessAddress last = end - 1; @@ -622,35 +446,35 @@ namespace ams::kern { const size_t region_size = this->GetRegionSize(state); const bool is_in_region = region_start <= addr && addr < end && last <= region_start + region_size - 1; - const bool is_in_heap = !(end <= m_region_starts[RegionType_Heap] || m_region_ends[RegionType_Heap] <= addr || m_region_starts[RegionType_Heap] == m_region_ends[RegionType_Heap]); - const bool is_in_alias = !(end <= m_region_starts[RegionType_Alias] || m_region_ends[RegionType_Alias] <= addr || m_region_starts[RegionType_Alias] == m_region_ends[RegionType_Alias]); + const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr || m_heap_region_start == m_heap_region_end); + const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr || m_alias_region_start == m_alias_region_end); switch (state) { - case ams::svc::MemoryState_Free: - case ams::svc::MemoryState_Kernel: + case KMemoryState_Free: + case KMemoryState_Kernel: return is_in_region; - case ams::svc::MemoryState_Io: - case ams::svc::MemoryState_Static: - case ams::svc::MemoryState_Code: - case ams::svc::MemoryState_CodeData: - case ams::svc::MemoryState_Shared: - case ams::svc::MemoryState_AliasCode: - case ams::svc::MemoryState_AliasCodeData: - case ams::svc::MemoryState_Stack: - case ams::svc::MemoryState_ThreadLocal: - case ams::svc::MemoryState_Transfered: - case ams::svc::MemoryState_SharedTransfered: - case ams::svc::MemoryState_SharedCode: - case ams::svc::MemoryState_GeneratedCode: - case ams::svc::MemoryState_CodeOut: - case ams::svc::MemoryState_Coverage: - case ams::svc::MemoryState_Insecure: + case KMemoryState_Io: + case KMemoryState_Static: + case KMemoryState_Code: + case KMemoryState_CodeData: + case KMemoryState_Shared: + case KMemoryState_AliasCode: + case KMemoryState_AliasCodeData: + case KMemoryState_Stack: + case KMemoryState_ThreadLocal: + case KMemoryState_Transfered: + case KMemoryState_SharedTransfered: + case KMemoryState_SharedCode: + case KMemoryState_GeneratedCode: + case KMemoryState_CodeOut: + case KMemoryState_Coverage: + case KMemoryState_Insecure: return is_in_region && !is_in_heap && !is_in_alias; - case ams::svc::MemoryState_Normal: + case KMemoryState_Normal: MESOSPHERE_ASSERT(is_in_heap); return is_in_region && !is_in_alias; - case ams::svc::MemoryState_Ipc: - case ams::svc::MemoryState_NonSecureIpc: - case ams::svc::MemoryState_NonDeviceIpc: + case KMemoryState_Ipc: + case KMemoryState_NonSecureIpc: + case KMemoryState_NonDeviceIpc: MESOSPHERE_ASSERT(is_in_alias); return is_in_region && !is_in_heap; default: @@ -658,11 +482,11 @@ namespace ams::kern { } } - Result KPageTableBase::CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { + Result KPageTableBase::CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { /* Validate the states match expectation. */ - 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_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_SUCCEED(); } @@ -673,26 +497,28 @@ 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) != it->GetAddress()) ? 1 : 0; + const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; while (true) { /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= it->GetLastAddress()) { + if (last_addr <= info.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) != it->GetEndAddress()) ? 1 : 0; + const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; if (out_blocks_needed != nullptr) { *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; @@ -701,32 +527,44 @@ namespace ams::kern { R_SUCCEED(); } - 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 { + Result KPageTableBase::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) const { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* 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; + /* Validate all blocks in the range have correct state. */ - const KMemoryState first_state = it->GetState(); - const KMemoryPermission first_perm = it->GetPermission(); - const KMemoryAttribute first_attr = it->GetAttribute(); + const KMemoryState first_state = info.m_state; + const KMemoryPermission first_perm = info.m_permission; + const KMemoryAttribute first_attr = info.m_attribute; while (true) { /* Validate the current block. */ - 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()); + 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()); /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= it->GetLastAddress()) { + if (last_addr <= info.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; + /* Write output state. */ if (out_state != nullptr) { *out_state = first_state; @@ -737,29 +575,9 @@ namespace ams::kern { if (out_attr != nullptr) { *out_attr = static_cast(first_attr & ~ignore_attr); } - - /* 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 != it->GetEndAddress()) ? 1 : 0; - *out_blocks_needed = blocks_for_end_align; + *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; } - - R_SUCCEED(); - } - - Result KPageTableBase::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) const { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - - /* Check memory state. */ - const KProcessAddress last_addr = addr + size - 1; - KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); - R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); - - /* If the start address isn't aligned, we need a block. */ - if (out_blocks_needed != nullptr && util::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) { - ++(*out_blocks_needed); - } - R_SUCCEED(); } @@ -887,7 +705,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const { + Result KPageTableBase::QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, KMemoryState state) const { MESOSPHERE_ASSERT(!this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(out != nullptr); @@ -904,7 +722,7 @@ namespace ams::kern { /* Begin traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; bool cur_valid = false; TraversalEntry next_entry; bool next_valid; @@ -921,7 +739,7 @@ namespace ams::kern { if (cur_valid && cur_entry.phys_addr <= address && address + size <= cur_entry.phys_addr + cur_entry.block_size) { /* Check if this region is valid. */ const KProcessAddress mapped_address = (region_start + tot_size) + (address - cur_entry.phys_addr); - if (R_SUCCEEDED(this->CheckMemoryState(mapped_address, size, KMemoryState_Mask, static_cast(util::ToUnderlying(state)), KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { + if (R_SUCCEEDED(this->CheckMemoryState(mapped_address, size, KMemoryState_All, state, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { /* It is! */ *out = mapped_address; R_SUCCEED(); @@ -1157,21 +975,24 @@ namespace ams::kern { /* Verify that the destination memory is aliasable code. */ size_t num_dst_allocator_blocks; - R_TRY(this->CheckMemoryStateContiguous(std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState_FlagCanCodeAlias, KMemoryState_FlagCanCodeAlias, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All & ~KMemoryAttribute_PermissionLocked, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState_FlagCanCodeAlias, KMemoryState_FlagCanCodeAlias, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); /* Determine whether any pages being unmapped are code. */ bool any_code_pages = false; { 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 ((it->GetState() & KMemoryState_FlagCode) != 0) { + if ((info.GetState() & KMemoryState_FlagCode) != 0) { any_code_pages = true; break; } /* Check if we're done. */ - if (dst_address + size - 1 <= it->GetLastAddress()) { + if (dst_address + size - 1 <= info.GetLastAddress()) { break; } @@ -1239,7 +1060,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::MapInsecurePhysicalMemory(KProcessAddress address, size_t size) { + Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) { /* Get the insecure memory resource limit and pool. */ auto * const insecure_resource_limit = KSystemControl::GetInsecureMemoryResourceLimit(); const auto insecure_pool = static_cast(KSystemControl::GetInsecureMemoryPool()); @@ -1251,7 +1072,7 @@ namespace ams::kern { /* Allocate pages for the insecure memory. */ KPageGroup pg(m_block_info_manager); - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), size / PageSize, 1, KMemoryManager::EncodeOption(insecure_pool, KMemoryManager::Direction_FromFront))); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), size / PageSize, KMemoryManager::EncodeOption(insecure_pool, KMemoryManager::Direction_FromFront))); /* Close the opened pages when we're done with them. */ /* If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed automatically. */ @@ -1295,7 +1116,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size) { + Result KPageTableBase::UnmapInsecureMemory(KProcessAddress address, size_t size) { /* Lock the table. */ KScopedLightLock lk(m_general_lock); @@ -1333,37 +1154,35 @@ 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; - 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 (num_pages <= region_num_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, (search_end - search_start) / alignment) * alignment; - const KProcessAddress candidate = search_start + random_offset; + 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; - KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate); - MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end()); + KMemoryInfo info; + ams::svc::PageInfo page_info; + MESOSPHERE_R_ABORT_UNLESS(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), candidate)); - 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; } + 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; } 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_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); + 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); } } - /* 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); @@ -1380,8 +1199,10 @@ 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) { - if (it->GetState() == state) { - total_size += it->GetSize(); + /* Get the memory info. */ + const KMemoryInfo info = it->GetMemoryInfo(); + if (info.GetState() == state) { + total_size += info.GetSize(); } } @@ -1404,14 +1225,14 @@ namespace ams::kern { return this->GetSize(KMemoryState_AliasCodeData); } - Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, const KPageProperties &properties) { + Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Create a page group to hold the pages we allocate. */ KPageGroup pg(m_block_info_manager); /* Allocate the pages. */ - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, 1, m_allocate_option)); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option)); /* Ensure that the page group is closed when we're done working with it. */ ON_SCOPE_EXIT { pg.Close(); }; @@ -1422,6 +1243,7 @@ namespace ams::kern { } /* Map the pages. */ + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_None }; R_RETURN(this->Operate(page_list, address, num_pages, pg, properties, OperationType_MapGroup, false)); } @@ -1473,14 +1295,17 @@ 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(GetInteger(it->GetAddress()), GetInteger(start_address)); - const KProcessAddress map_end_address = std::min(GetInteger(it->GetEndAddress()), GetInteger(end_address)); + KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address)); + const KProcessAddress map_end_address = std::min(info.GetEndAddress(), GetInteger(end_address)); MESOSPHERE_ABORT_UNLESS(map_end_address != map_address); /* Determine if we should disable head merge. */ - 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 }; + 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 }; /* While we have pages to map, map them. */ size_t map_pages = (map_end_address - map_address) / PageSize; @@ -1509,7 +1334,7 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= it->GetLastAddress()) { + if (last_address <= info.GetLastAddress()) { break; } @@ -1669,12 +1494,11 @@ namespace ams::kern { /* Begin a traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address), svc::ResultInvalidCurrentMemory()); /* Traverse until we have enough size or we aren't contiguous any more. */ const KPhysicalAddress phys_address = cur_entry.phys_addr; - const u8 entry_attr = cur_entry.attr; size_t contig_size; for (contig_size = cur_entry.block_size - (GetInteger(phys_address) & (cur_entry.block_size - 1)); contig_size < size; contig_size += cur_entry.block_size) { if (!impl.ContinueTraversal(std::addressof(cur_entry), std::addressof(context))) { @@ -1683,9 +1507,6 @@ namespace ams::kern { if (cur_entry.phys_addr != phys_address + contig_size) { break; } - if (cur_entry.attr != entry_attr) { - break; - } } /* Take the minimum size for our region. */ @@ -1699,7 +1520,7 @@ namespace ams::kern { } /* The memory is contiguous, so set the output range. */ - out->Set(phys_address, size, is_heap, attr); + out->Set(phys_address, size, is_heap); R_SUCCEED(); } @@ -1784,29 +1605,19 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); - /* 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) { - for (const auto &block : pg) { - cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()); - } - cpu::InvalidateEntireInstructionCache(); - } - /* Perform mapping operation. */ const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; - const auto operation = was_x ? OperationType_ChangePermissionsAndRefresh : OperationType_ChangePermissions; + 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); /* Ensure cache coherency, if we're setting pages as executable. */ - if (was_x) { + if (is_x) { + for (const auto &block : pg) { + cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()); + } cpu::InvalidateEntireInstructionCache(); } @@ -1826,10 +1637,9 @@ namespace ams::kern { KMemoryAttribute old_attr; size_t num_allocator_blocks; constexpr u32 AttributeTestMask = ~(KMemoryAttribute_SetMask | KMemoryAttribute_DeviceShared); - const u32 state_test_mask = ((mask & KMemoryAttribute_Uncached) ? static_cast(KMemoryState_FlagCanChangeAttribute) : 0) | ((mask & KMemoryAttribute_PermissionLocked) ? static_cast(KMemoryState_FlagCanPermissionLock) : 0); R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr), std::addressof(num_allocator_blocks), addr, size, - state_test_mask, state_test_mask, + KMemoryState_FlagCanChangeAttribute, KMemoryState_FlagCanChangeAttribute, KMemoryPermission_None, KMemoryPermission_None, AttributeTestMask, KMemoryAttribute_None, ~AttributeTestMask)); @@ -1841,18 +1651,15 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); - /* If we need to, perform a change attribute operation. */ - if ((mask & KMemoryAttribute_Uncached) != 0) { - /* Determine the new attribute. */ - const KMemoryAttribute new_attr = static_cast(((old_attr & ~mask) | (attr & mask))); + /* Determine the new attribute. */ + const KMemoryAttribute new_attr = static_cast(((old_attr & ~mask) | (attr & mask))); - /* Perform operation. */ - const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None }; - R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, OperationType_ChangePermissionsAndRefreshAndFlush, false)); - } + /* Perform operation. */ + const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None }; + R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, OperationType_ChangePermissionsAndRefreshAndFlush, false)); /* Update the blocks. */ - m_memory_block_manager.UpdateAttribute(std::addressof(allocator), addr, num_pages, mask, attr); + m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, old_perm, new_attr, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); R_SUCCEED(); } @@ -1869,17 +1676,17 @@ namespace ams::kern { KScopedLightLock lk(m_general_lock); /* Validate that setting heap size is possible at all. */ - R_UNLESS(!m_is_kernel, svc::ResultOutOfMemory()); - R_UNLESS(size <= static_cast(m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]), svc::ResultOutOfMemory()); - R_UNLESS(size <= m_max_heap_size, svc::ResultOutOfMemory()); + R_UNLESS(!m_is_kernel, svc::ResultOutOfMemory()); + R_UNLESS(size <= static_cast(m_heap_region_end - m_heap_region_start), svc::ResultOutOfMemory()); + R_UNLESS(size <= m_max_heap_size, svc::ResultOutOfMemory()); - if (size < static_cast(m_current_heap_end - m_region_starts[RegionType_Heap])) { + if (size < static_cast(m_current_heap_end - m_heap_region_start)) { /* The size being requested is less than the current size, so we need to free the end of the heap. */ /* Validate memory state. */ size_t num_allocator_blocks; R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), - m_region_starts[RegionType_Heap] + size, (m_current_heap_end - m_region_starts[RegionType_Heap]) - size, + m_heap_region_start + size, (m_current_heap_end - m_heap_region_start) - size, KMemoryState_All, KMemoryState_Normal, KMemoryPermission_All, KMemoryPermission_UserReadWrite, KMemoryAttribute_All, KMemoryAttribute_None)); @@ -1893,30 +1700,30 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Unmap the end of the heap. */ - const size_t num_pages = ((m_current_heap_end - m_region_starts[RegionType_Heap]) - size) / PageSize; + const size_t num_pages = ((m_current_heap_end - m_heap_region_start) - size) / PageSize; const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - R_TRY(this->Operate(updater.GetPageList(), m_region_starts[RegionType_Heap] + size, num_pages, Null, false, unmap_properties, OperationType_Unmap, false)); + R_TRY(this->Operate(updater.GetPageList(), m_heap_region_start + size, num_pages, Null, false, unmap_properties, OperationType_Unmap, false)); /* Release the memory from the resource limit. */ m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, num_pages * PageSize); /* Apply the memory block update. */ - m_memory_block_manager.Update(std::addressof(allocator), m_region_starts[RegionType_Heap] + size, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, size == 0 ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, size == 0 ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None); /* Update the current heap end. */ - m_current_heap_end = m_region_starts[RegionType_Heap] + size; + m_current_heap_end = m_heap_region_start + size; /* Set the output. */ - *out = m_region_starts[RegionType_Heap]; + *out = m_heap_region_start; R_SUCCEED(); - } else if (size == static_cast(m_current_heap_end - m_region_starts[RegionType_Heap])) { + } else if (size == static_cast(m_current_heap_end - m_heap_region_start)) { /* The size requested is exactly the current size. */ - *out = m_region_starts[RegionType_Heap]; + *out = m_heap_region_start; R_SUCCEED(); } else { /* We have to allocate memory. Determine how much to allocate and where while the table is locked. */ cur_address = m_current_heap_end; - allocation_size = size - (m_current_heap_end - m_region_starts[RegionType_Heap]); + allocation_size = size - (m_current_heap_end - m_heap_region_start); } } @@ -1926,7 +1733,7 @@ namespace ams::kern { /* Allocate pages for the heap extension. */ KPageGroup pg(m_block_info_manager); - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), allocation_size / PageSize, 1, m_allocate_option)); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), allocation_size / PageSize, m_allocate_option)); /* Close the opened pages when we're done with them. */ /* If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed automatically. */ @@ -1959,20 +1766,20 @@ namespace ams::kern { /* Map the pages. */ const size_t num_pages = allocation_size / PageSize; - const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, (m_current_heap_end == m_region_starts[RegionType_Heap]) ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; + const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, (m_current_heap_end == m_heap_region_start) ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), m_current_heap_end, num_pages, pg, map_properties, OperationType_MapGroup, false)); /* We succeeded, so commit our memory reservation. */ memory_reservation.Commit(); /* Apply the memory block update. */ - m_memory_block_manager.Update(std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, m_region_starts[RegionType_Heap] == m_current_heap_end ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, m_heap_region_start == m_current_heap_end ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); /* Update the current heap end. */ - m_current_heap_end = m_region_starts[RegionType_Heap] + size; + m_current_heap_end = m_heap_region_start + size; /* Set the output. */ - *out = m_region_starts[RegionType_Heap]; + *out = m_heap_region_start; R_SUCCEED(); } } @@ -2024,18 +1831,19 @@ namespace ams::kern { address = util::AlignDown(GetInteger(address), PageSize); /* Verify that we can query the address. */ - KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); - R_UNLESS(it != m_memory_block_manager.end(), svc::ResultInvalidCurrentMemory()); + KMemoryInfo info; + ams::svc::PageInfo page_info; + R_TRY(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), address)); /* Check the memory state. */ - R_TRY(this->CheckMemoryState(it, KMemoryState_FlagCanQueryPhysical, KMemoryState_FlagCanQueryPhysical, KMemoryPermission_UserReadExecute, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(info, 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 = it->GetAddress(); - KProcessAddress end_addr = it->GetEndAddress(); + KProcessAddress virt_addr = info.GetAddress(); + KProcessAddress end_addr = info.GetEndAddress(); /* Perform traversal. */ { @@ -2091,7 +1899,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryState state, KMemoryPermission perm) { + Result KPageTableBase::MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); @@ -2103,11 +1911,11 @@ namespace ams::kern { const KPhysicalAddress last = phys_addr + size - 1; /* Get region extents. */ - const KProcessAddress region_start = m_region_starts[RegionType_KernelMap]; - const size_t region_size = m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; + const KProcessAddress region_start = m_kernel_map_region_start; + const size_t region_size = m_kernel_map_region_end - m_kernel_map_region_start; const size_t region_num_pages = region_size / PageSize; - MESOSPHERE_ASSERT(this->CanContain(region_start, region_size, state)); + MESOSPHERE_ASSERT(this->CanContain(region_start, region_size, KMemoryState_Io)); /* Locate the memory region. */ const KMemoryRegion *region = KMemoryLayout::Find(phys_addr); @@ -2137,16 +1945,10 @@ namespace ams::kern { /* Select an address to map at. */ KProcessAddress addr = Null; + const size_t phys_alignment = std::min(std::min(util::GetAlignment(GetInteger(phys_addr)), util::GetAlignment(size)), MaxPhysicalMapAlignment); for (s32 block_type = KPageTable::GetMaxBlockType(); block_type >= 0; block_type--) { const size_t alignment = KPageTable::GetBlockSize(static_cast(block_type)); - - const KPhysicalAddress aligned_phys = util::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1; - if (aligned_phys <= phys_addr) { - continue; - } - - const KPhysicalAddress last_aligned_paddr = util::AlignDown(GetInteger(last) + 1, alignment) - 1; - if (!(last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr)) { + if (alignment > phys_alignment) { continue; } @@ -2158,11 +1960,11 @@ namespace ams::kern { R_UNLESS(addr != Null, svc::ResultOutOfMemory()); /* Check that we can map IO here. */ - MESOSPHERE_ASSERT(this->CanContain(addr, size, state)); + MESOSPHERE_ASSERT(this->CanContain(addr, size, KMemoryState_Io)); MESOSPHERE_R_ASSERT(this->CheckMemoryState(addr, size, KMemoryState_All, KMemoryState_Free, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); /* Perform mapping operation. */ - const KPageProperties properties = { perm, state == KMemoryState_IoRegister, false, DisableMergeAttribute_DisableHead }; + const KPageProperties properties = { perm, true, false, DisableMergeAttribute_DisableHead }; R_TRY(this->Operate(page_list, addr, num_pages, phys_addr, true, properties, OperationType_Map, false)); /* Set the output address. */ @@ -2185,10 +1987,10 @@ namespace ams::kern { /* Map the io memory. */ KProcessAddress addr; - R_TRY(this->MapIoImpl(std::addressof(addr), updater.GetPageList(), phys_addr, size, KMemoryState_IoRegister, perm)); + R_TRY(this->MapIoImpl(std::addressof(addr), updater.GetPageList(), phys_addr, size, perm)); /* Update the blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), addr, size / PageSize, KMemoryState_IoRegister, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), addr, size / PageSize, KMemoryState_Io, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); /* We successfully mapped the pages. */ R_SUCCEED(); @@ -2218,8 +2020,7 @@ namespace ams::kern { R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, phys_addr, true, properties, OperationType_Map, false)); /* Update the blocks. */ - const auto state = mapping == ams::svc::MemoryMapping_Memory ? KMemoryState_IoMemory : KMemoryState_IoRegister; - m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, state, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, KMemoryState_Io, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); /* We successfully mapped the pages. */ R_SUCCEED(); @@ -2238,7 +2039,7 @@ namespace ams::kern { size_t num_allocator_blocks; R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr), std::addressof(num_allocator_blocks), dst_address, size, - KMemoryState_All, mapping == ams::svc::MemoryMapping_Memory ? KMemoryState_IoMemory : KMemoryState_IoRegister, + KMemoryState_All, KMemoryState_Io, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_Locked)); @@ -2328,16 +2129,10 @@ namespace ams::kern { /* Select an address to map at. */ KProcessAddress addr = Null; + const size_t phys_alignment = std::min(std::min(util::GetAlignment(GetInteger(phys_addr)), util::GetAlignment(size)), MaxPhysicalMapAlignment); for (s32 block_type = KPageTable::GetMaxBlockType(); block_type >= 0; block_type--) { const size_t alignment = KPageTable::GetBlockSize(static_cast(block_type)); - - const KPhysicalAddress aligned_phys = util::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1; - if (aligned_phys <= phys_addr) { - continue; - } - - const KPhysicalAddress last_aligned_paddr = util::AlignDown(GetInteger(last) + 1, alignment) - 1; - if (!(last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr)) { + if (alignment > phys_alignment) { continue; } @@ -2413,11 +2208,11 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Perform mapping operation. */ - const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; if (is_pa_valid) { + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, phys_addr, true, properties, OperationType_Map, false)); } else { - R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, properties)); + R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, perm)); } /* Update the blocks. */ @@ -2449,8 +2244,7 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Map the pages. */ - const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; - R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, properties)); + R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, perm)); /* Update the blocks. */ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, state, perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); @@ -2514,7 +2308,7 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Perform mapping operation. */ - const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; + const KPageProperties properties = { perm, state == KMemoryState_Io, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); /* Update the blocks. */ @@ -2548,13 +2342,8 @@ 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 }; + const KPageProperties properties = { perm, state == KMemoryState_Io, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); /* Update the blocks. */ @@ -2576,9 +2365,8 @@ 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(nullptr, std::addressof(old_perm), nullptr, std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(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()); @@ -2595,11 +2383,6 @@ 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); @@ -2696,54 +2479,18 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size) { - /* Check pre-condition: this is being called on the current process. */ - MESOSPHERE_ASSERT(this == std::addressof(GetCurrentProcess().GetPageTable().GetBasePageTable())); - - /* Check that the region is in range. */ - R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); - - /* Lock the table. */ - KScopedLightLock lk(m_general_lock); - - /* Check the memory state. */ - R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagReferenceCounted, KMemoryState_FlagReferenceCounted, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_Uncached, KMemoryAttribute_None)); - - /* Invalidate the data cache. */ - R_RETURN(cpu::InvalidateDataCache(GetVoidPointer(address), 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) { + Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { /* 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-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)); + /* 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)); if (!can_read) { - R_UNLESS(this->CanReadWriteDebugMemory(address, size, force_debug_prod), svc::ResultInvalidCurrentMemory()); + 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()); } /* Get the impl. */ @@ -2825,10 +2572,11 @@ namespace ams::kern { /* Lock the table. */ KScopedLightLock lk(m_general_lock); - /* 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()); + /* 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()); } /* Get the impl. */ @@ -2905,7 +2653,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size, KMemoryState state) { + Result KPageTableBase::ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); @@ -2919,7 +2667,7 @@ namespace ams::kern { /* Temporarily map the io memory. */ KProcessAddress io_addr; - R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, state, KMemoryPermission_UserRead)); + R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, KMemoryPermission_UserRead)); /* Ensure we unmap the io memory when we're done with it. */ ON_SCOPE_EXIT { @@ -2950,7 +2698,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size, KMemoryState state) { + Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); @@ -2964,7 +2712,7 @@ namespace ams::kern { /* Temporarily map the io memory. */ KProcessAddress io_addr; - R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, state, KMemoryPermission_UserReadWrite)); + R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, KMemoryPermission_UserReadWrite)); /* Ensure we unmap the io memory when we're done with it. */ ON_SCOPE_EXIT { @@ -2995,7 +2743,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) { + Result KPageTableBase::ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size) { /* Lightly validate the range before doing anything else. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); @@ -3007,7 +2755,7 @@ namespace ams::kern { KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock); /* Check that the desired range is readable io memory. */ - R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, state, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, KMemoryState_Io, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); /* Read the memory. */ u8 *dst = static_cast(buffer); @@ -3018,10 +2766,10 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), address)); /* Determine the current read size. */ - const size_t cur_size = std::min(last_address - address + 1, PageSize - (GetInteger(address) & (PageSize - 1))); + const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); /* Read. */ - R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size, state)); + R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size)); /* Advance. */ address += cur_size; @@ -3031,7 +2779,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state) { + Result KPageTableBase::WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size) { /* Lightly validate the range before doing anything else. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); @@ -3043,7 +2791,7 @@ namespace ams::kern { KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock); /* Check that the desired range is writable io memory. */ - R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, state, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, KMemoryState_Io, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); /* Read the memory. */ const u8 *src = static_cast(buffer); @@ -3054,10 +2802,10 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), address)); /* Determine the current read size. */ - const size_t cur_size = std::min(last_address - address + 1, PageSize - (GetInteger(address) & (PageSize - 1))); + const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); /* Read. */ - R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size, state)); + R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size)); /* Advance. */ address += cur_size; @@ -3090,7 +2838,7 @@ namespace ams::kern { m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, &KMemoryBlock::ShareToDevice, KMemoryPermission_None); /* Set whether the locked memory was io. */ - *out_is_io = static_cast(old_state & KMemoryState_Mask) == ams::svc::MemoryState_Io; + *out_is_io = old_state == KMemoryState_Io; R_SUCCEED(); } @@ -3830,7 +3578,7 @@ namespace ams::kern { R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); /* Get the source permission. */ - const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? (KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped) : KMemoryPermission_UserRead); + const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped : KMemoryPermission_UserRead); /* Get aligned extents. */ const KProcessAddress aligned_src_start = util::AlignDown(GetInteger(address), PageSize); @@ -3847,15 +3595,15 @@ namespace ams::kern { switch (dst_state) { case KMemoryState_Ipc: test_state = KMemoryState_FlagCanUseIpc; - test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_IpcLocked)); + test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked; break; case KMemoryState_NonSecureIpc: test_state = KMemoryState_FlagCanUseNonSecureIpc; - test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); + test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; break; case KMemoryState_NonDeviceIpc: test_state = KMemoryState_FlagCanUseNonDeviceIpc; - test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); + test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; break; default: R_THROW(svc::ResultInvalidCombination()); @@ -3874,25 +3622,27 @@ namespace ams::kern { /* Iterate, mapping as needed. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(aligned_src_start); while (true) { - /* Validate the current block. */ - R_TRY(this->CheckMemoryState(it, test_state, test_state, test_perm, test_perm, test_attr_mask, KMemoryAttribute_None)); + const KMemoryInfo info = it->GetMemoryInfo(); - 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); + /* Validate the current block. */ + R_TRY(this->CheckMemoryState(info, 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); const size_t cur_size = cur_end - cur_start; - if (GetInteger(it->GetAddress()) < GetInteger(mapping_src_start)) { + if (info.GetAddress() < GetInteger(mapping_src_start)) { ++blocks_needed; } - if (mapping_src_last < GetInteger(it->GetLastAddress())) { + if (mapping_src_last < info.GetLastAddress()) { ++blocks_needed; } /* Set the permissions on the block, if we need to. */ - 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; + 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; 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)); } @@ -3902,7 +3652,7 @@ namespace ams::kern { } /* If the block is at the end, we're done. */ - if (aligned_src_last <= GetInteger(it->GetLastAddress())) { + if (aligned_src_last <= info.GetLastAddress()) { break; } @@ -3924,8 +3674,8 @@ namespace ams::kern { MESOSPHERE_ASSERT(src_page_table.IsLockedByCurrentThread()); /* Check that we can theoretically map. */ - const KProcessAddress region_start = m_region_starts[RegionType_Alias]; - const size_t region_size = m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; + const KProcessAddress region_start = m_alias_region_start; + const size_t region_size = m_alias_region_end - m_alias_region_start; R_UNLESS(size < region_size, svc::ResultOutOfAddressSpace()); /* Get aligned source extents. */ @@ -4157,7 +3907,7 @@ namespace ams::kern { const size_t src_map_size = src_map_end - src_map_start; /* Ensure that we clean up appropriately if we fail after this. */ - const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? (KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped) : KMemoryPermission_UserRead); + const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped : KMemoryPermission_UserRead); ON_RESULT_FAILURE { if (src_map_end > src_map_start) { src_page_table.CleanupForIpcClientOnServerSetupFailure(updater.GetPageList(), src_map_start, src_map_size, src_perm); @@ -4266,50 +4016,56 @@ namespace ams::kern { const auto mapped_last = mapped_end - 1; /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = cur_it; + KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = start_it; ++next_it; + /* Get the current block info. */ + KMemoryInfo cur_info = start_it->GetMemoryInfo(); + /* Create tracking variables. */ - 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; + 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; 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_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()) { + 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()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_it->GetSize(); + cur_size += next_info.GetSize(); } else { /* We have to operate on the current block. */ if ((cur_needs_set_perm || first) && !cur_perm_eq) { - const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_info.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_it->GetAddress(); - cur_size = next_it->GetSize(); + cur_address = next_info.GetAddress(); + cur_size = next_info.GetSize(); first = false; } /* Advance. */ + cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - - cur_it = next_it++; + ++next_it; } /* Process the last block. */ if ((first || cur_needs_set_perm) && !cur_perm_eq) { - const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_info.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)); } } @@ -4318,37 +4074,41 @@ namespace ams::kern { /* Iterate, reprotecting as needed. */ { /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = cur_it; + KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = start_it; ++next_it; /* Validate the current block. */ - MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(cur_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + 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)); /* Create tracking variables. */ - 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; + 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; 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_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(next_info, 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_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()) { + 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()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_it->GetSize(); + cur_size += next_info.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_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.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)); } @@ -4356,24 +4116,24 @@ namespace ams::kern { mapped_size += cur_size; /* Advance. */ - cur_address = next_it->GetAddress(); - cur_size = next_it->GetSize(); + cur_address = next_info.GetAddress(); + cur_size = next_info.GetSize(); first = false; } /* Advance. */ + cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - - cur_it = next_it++; + ++next_it; } /* Process the last block. */ - const auto lock_count = cur_it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = cur_info.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_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.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)); } } @@ -4406,36 +4166,38 @@ namespace ams::kern { /* Iterate over blocks, fixing permissions. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); while (true) { - 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(); + 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(); /* If we can, fix the protections on the block. */ - if ((it->GetIpcLockCount() == 0 && (it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || - (it->GetIpcLockCount() != 0 && (it->GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) + if ((info.GetIpcLockCount() == 0 && (info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || + (info.GetIpcLockCount() != 0 && (info.GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) { /* Check if we actually need to fix the protections on the block. */ - 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); + 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); const DisableMergeAttribute head_body_attr = start_nc ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None; DisableMergeAttribute tail_attr; - if (cur_end == src_map_end && it->GetEndAddress() == src_map_end) { + if (cur_end == src_map_end && info.GetEndAddress() == src_map_end) { auto next_it = it; ++next_it; - const auto lock_count = it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = info.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 = { it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { info.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 <= it->GetLastAddress()) { + if (src_map_last <= info.GetLastAddress()) { break; } @@ -4474,21 +4236,24 @@ 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 <= it->GetLastAddress()) { - if (it->GetState() != KMemoryState_Free) { + if (last_address <= info.GetLastAddress()) { + if (info.GetState() != KMemoryState_Free) { mapped_size += (last_address + 1 - cur_address); } break; } /* Track the memory if it's mapped. */ - if (it->GetState() != KMemoryState_Free) { - mapped_size += it->GetEndAddress() - cur_address; + if (info.GetState() != KMemoryState_Free) { + mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } @@ -4530,18 +4295,21 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - const bool is_free = it->GetState() == KMemoryState_Free; + /* Get the memory info. */ + const KMemoryInfo info = it->GetMemoryInfo(); + + const bool is_free = info.GetState() == KMemoryState_Free; if (is_free) { - if (it->GetAddress() < GetInteger(address)) { + if (info.GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < it->GetLastAddress()) { + if (last_address < info.GetLastAddress()) { ++num_allocator_blocks; } } /* Check if we're done. */ - if (last_address <= it->GetLastAddress()) { + if (last_address <= info.GetLastAddress()) { if (!is_free) { checked_mapped_size += (last_address + 1 - cur_address); } @@ -4550,11 +4318,11 @@ namespace ams::kern { /* Track the memory if it's mapped. */ if (!is_free) { - checked_mapped_size += it->GetEndAddress() - cur_address; + checked_mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } @@ -4594,23 +4362,26 @@ 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 (it->GetState() == KMemoryState_Free) { + if (info.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(it->GetEndAddress() - cur_address, last_unmap_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(KProcessAddress(info.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 <= it->GetLastAddress()) { + if (last_unmap_address <= info.GetLastAddress()) { break; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } } @@ -4629,57 +4400,48 @@ 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 (it->GetState() == KMemoryState_Free) { + if (info.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(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; + const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, DisableMergeAttribute_None }; + size_t map_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; /* While we have pages to map, map them. */ - { - /* Create a page group for the current mapping range. */ - KPageGroup cur_pg(m_block_info_manager); - { - ON_RESULT_FAILURE { - cur_pg.OpenFirst(); - cur_pg.Close(); - }; + while (map_pages > 0) { + /* Check if we're at the end of the physical block. */ + if (pg_pages == 0) { + /* Ensure there are more pages to map. */ + MESOSPHERE_ASSERT(pg_it != pg.end()); - size_t remain_pages = map_pages; - while (remain_pages > 0) { - /* Check if we're at the end of the physical block. */ - if (pg_pages == 0) { - /* Ensure there are more pages to map. */ - MESOSPHERE_ASSERT(pg_it != pg.end()); - - /* Advance our physical block. */ - ++pg_it; - pg_phys_addr = pg_it->GetAddress(); - pg_pages = pg_it->GetNumPages(); - } - - /* Add whatever we can to the current block. */ - const size_t cur_pages = std::min(pg_pages, remain_pages); - R_TRY(cur_pg.AddBlock(pg_phys_addr + ((pg_pages - cur_pages) * PageSize), cur_pages)); - - /* Advance. */ - remain_pages -= cur_pages; - pg_pages -= cur_pages; - } + /* Advance our physical block. */ + ++pg_it; + pg_phys_addr = pg_it->GetAddress(); + pg_pages = pg_it->GetNumPages(); } - /* Map the pages. */ - R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages, cur_pg, map_properties, OperationType_MapFirstGroup, false)); + /* Map whatever we can. */ + const size_t cur_pages = std::min(pg_pages, map_pages); + R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_pages, pg_phys_addr, true, map_properties, OperationType_MapFirst, false)); + + /* Advance. */ + cur_address += cur_pages * PageSize; + map_pages -= cur_pages; + + pg_phys_addr += cur_pages * PageSize; + pg_pages -= cur_pages; } } /* Check if we're done. */ - if (last_address <= it->GetLastAddress()) { + if (last_address <= info.GetLastAddress()) { break; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } @@ -4692,9 +4454,7 @@ namespace ams::kern { /* Update the relevant memory blocks. */ m_memory_block_manager.UpdateIfMatch(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, - KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, - address == this->GetAliasRegionStart() ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, - KMemoryBlockDisableMergeAttribute_None); + KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None); R_SUCCEED(); } @@ -4731,23 +4491,26 @@ 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 = it->GetState() == KMemoryState_Normal && it->GetAttribute() == 0; - const bool is_free = it->GetState() == KMemoryState_Free; + const bool is_normal = info.GetState() == KMemoryState_Normal && info.GetAttribute() == 0; + const bool is_free = info.GetState() == KMemoryState_Free; R_UNLESS(is_normal || is_free, svc::ResultInvalidCurrentMemory()); if (is_normal) { - R_UNLESS(it->GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); + R_UNLESS(info.GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); if (map_start_address == Null) { map_start_address = cur_address; } - map_last_address = (last_address >= it->GetLastAddress()) ? it->GetLastAddress() : last_address; + map_last_address = (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address; - if (it->GetAddress() < GetInteger(address)) { + if (info.GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < it->GetLastAddress()) { + if (last_address < info.GetLastAddress()) { ++num_allocator_blocks; } @@ -4755,12 +4518,12 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= it->GetLastAddress()) { + if (last_address <= info.GetLastAddress()) { break; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } @@ -4786,30 +4549,30 @@ namespace ams::kern { /* Iterate over the memory, unmapping as we go. */ auto it = m_memory_block_manager.FindIterator(cur_address); - - const auto clear_merge_attr = (it->GetState() == KMemoryState_Normal && it->GetAddress() == this->GetAliasRegionStart() && it->GetAddress() == address) ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None; - while (true) { /* 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 (it->GetState() == KMemoryState_Normal) { + if (info.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(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(KProcessAddress(info.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 <= it->GetLastAddress()) { + if (last_address <= info.GetLastAddress()) { break; } /* Advance. */ - cur_address = it->GetEndAddress(); + cur_address = info.GetEndAddress(); ++it; } @@ -4818,7 +4581,7 @@ namespace ams::kern { m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, mapped_size); /* Update memory blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, clear_merge_attr); + m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); /* We succeeded. */ R_SUCCEED(); @@ -4836,7 +4599,7 @@ namespace ams::kern { /* Allocate the new memory. */ const size_t num_pages = size / PageSize; - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, 1, KMemoryManager::EncodeOption(KMemoryManager::Pool_Unsafe, KMemoryManager::Direction_FromFront))); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, KMemoryManager::EncodeOption(KMemoryManager::Pool_Unsafe, KMemoryManager::Direction_FromFront))); /* Close the page group when we're done with it. */ ON_SCOPE_EXIT { pg.Close(); }; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 08a79f5c0..35c6959b3 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -51,7 +51,7 @@ namespace ams::kern { } } - /* Wait for all children threads to terminate. */ + /* Wait for all children threads to terminate.*/ while (true) { /* Get the next child. */ KThread *cur_child = nullptr; @@ -220,8 +220,18 @@ namespace ams::kern { m_running_thread_switch_counts[i] = 0; } - /* Set max memory. */ - m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(m_flags), KAddressSpaceInfo::Type_Heap); + /* 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(); + } /* Generate random entropy. */ KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); @@ -253,45 +263,28 @@ namespace ams::kern { MESOSPHERE_ASSERT(res_limit != nullptr); MESOSPHERE_ABORT_UNLESS((params.code_num_pages * PageSize) / PageSize == static_cast(params.code_num_pages)); + /* Determine is application. */ + const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication) != 0; + /* Set members. */ - m_memory_pool = pool; - m_resource_limit = res_limit; - m_is_default_application_system_resource = false; - m_is_immortal = immortal; + m_memory_pool = pool; + m_resource_limit = res_limit; + m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); + m_is_immortal = immortal; - /* Setup our system resource. */ - if (const size_t system_resource_num_pages = params.system_resource_num_pages; system_resource_num_pages != 0) { - /* Create a secure system resource. */ - KSecureSystemResource *secure_resource = KSecureSystemResource::Create(); - R_UNLESS(secure_resource != nullptr, svc::ResultOutOfResource()); - - ON_RESULT_FAILURE { secure_resource->Close(); }; - - /* Initialize the secure resource. */ - R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, m_resource_limit, m_memory_pool)); - - /* Set our system resource. */ - m_system_resource = secure_resource; - } else { - /* Use the system-wide system resource. */ - const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); - m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); - - m_is_default_application_system_resource = is_app; - - /* Open reference to the system resource. */ - m_system_resource->Open(); - } - - /* Ensure we clean up our secure resource, if we fail. */ - ON_RESULT_FAILURE { m_system_resource->Close(); }; + /* Open reference to our system resource. */ + m_system_resource->Open(); /* Setup page table. */ + /* NOTE: Nintendo passes process ID despite not having set it yet. */ + /* This goes completely unused, but even so... */ { - 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, this->GetSlabIndex())); + const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); + const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; + const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; + R_TRY(m_page_table.Initialize(m_process_id, as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); } - ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; + ON_RESULT_FAILURE { m_page_table.Finalize(); }; /* Ensure we can insert the code region. */ R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, KMemoryState_Code), svc::ResultInvalidMemoryRegion()); @@ -322,10 +315,9 @@ namespace ams::kern { MESOSPHERE_ASSERT(res_limit != nullptr); /* Set pool and resource limit. */ - m_memory_pool = pool; - m_resource_limit = res_limit; - m_is_default_application_system_resource = false; - m_is_immortal = false; + m_memory_pool = pool; + m_resource_limit = res_limit; + m_is_immortal = false; /* Get the memory sizes. */ const size_t code_num_pages = params.code_num_pages; @@ -356,8 +348,6 @@ namespace ams::kern { const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); - m_is_default_application_system_resource = is_app; - /* Open reference to the system resource. */ m_system_resource->Open(); } @@ -366,9 +356,13 @@ namespace ams::kern { ON_RESULT_FAILURE { m_system_resource->Close(); }; /* Setup page table. */ + /* NOTE: Nintendo passes process ID despite not having set it yet. */ + /* This goes completely unused, but even so... */ { - 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, this->GetSlabIndex())); + const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); + const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; + const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; + R_TRY(m_page_table.Initialize(m_process_id, as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, code_size, m_system_resource, res_limit)); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -453,7 +447,7 @@ namespace ams::kern { void KProcess::Exit() { MESOSPHERE_ASSERT_THIS(); - /* Determine whether we need to start terminating. */ + /* Determine whether we need to start terminating */ bool needs_terminate = false; { KScopedLightLock lk(m_state_lock); @@ -477,7 +471,7 @@ namespace ams::kern { MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name); /* Register the process as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); } /* Exit the current thread. */ @@ -522,7 +516,7 @@ namespace ams::kern { MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name); /* Register the process as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); } } @@ -854,7 +848,7 @@ namespace ams::kern { size_t KProcess::GetUsedUserPhysicalMemorySize() const { const size_t norm_size = m_page_table.GetNormalMemorySize(); const size_t other_size = m_code_size + m_main_thread_stack_size; - const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault(); + const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; return norm_size + other_size + sec_size; } @@ -862,20 +856,13 @@ namespace ams::kern { size_t KProcess::GetTotalUserPhysicalMemorySize() const { /* Get the amount of free and used size. */ const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax); + const size_t used_size = this->GetUsedUserPhysicalMemorySize(); const size_t max_size = m_max_process_memory; - /* Determine used size. */ - /* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */ - const size_t norm_size = m_page_table.GetNormalMemorySize(); - const size_t other_size = m_code_size + m_main_thread_stack_size; - const size_t sec_size = this->GetRequiredSecureMemorySize(); - const size_t used_size = norm_size + other_size + sec_size; - - /* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */ if (used_size + free_size > max_size) { return max_size; } else { - return free_size + this->GetUsedUserPhysicalMemorySize(); + return free_size + used_size; } } @@ -889,20 +876,14 @@ namespace ams::kern { size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const { /* Get the amount of free and used size. */ const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax); + const size_t used_size = this->GetUsedUserPhysicalMemorySize(); + const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; const size_t max_size = m_max_process_memory; - /* Determine used size. */ - /* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */ - const size_t norm_size = m_page_table.GetNormalMemorySize(); - const size_t other_size = m_code_size + m_main_thread_stack_size; - const size_t sec_size = this->GetRequiredSecureMemorySize(); - const size_t used_size = norm_size + other_size + sec_size; - - /* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */ if (used_size + free_size > max_size) { - return max_size - this->GetRequiredSecureMemorySizeNonDefault(); + return max_size - sec_size; } else { - return free_size + this->GetUsedNonSystemUserPhysicalMemorySize(); + return free_size + used_size - sec_size; } } @@ -924,6 +905,7 @@ 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_server_port.cpp b/libraries/libmesosphere/source/kern_k_server_port.cpp index 82223bfe3..765b14391 100644 --- a/libraries/libmesosphere/source/kern_k_server_port.cpp +++ b/libraries/libmesosphere/source/kern_k_server_port.cpp @@ -36,7 +36,7 @@ namespace ams::kern { /* Cleanup the session list. */ while (true) { - /* Get the last session in the list. */ + /* Get the last session in the list */ KServerSession *session = nullptr; { KScopedSchedulerLock sl; @@ -56,7 +56,7 @@ namespace ams::kern { /* Cleanup the light session list. */ while (true) { - /* Get the last session in the list. */ + /* Get the last session in the list */ KLightServerSession *session = nullptr; { KScopedSchedulerLock sl; diff --git a/libraries/libmesosphere/source/kern_k_server_session.cpp b/libraries/libmesosphere/source/kern_k_server_session.cpp index 7c8c4e91c..035aa3980 100644 --- a/libraries/libmesosphere/source/kern_k_server_session.cpp +++ b/libraries/libmesosphere/source/kern_k_server_session.cpp @@ -650,7 +650,7 @@ namespace ams::kern { const auto src_state = src_user ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; /* Determine the source permission. User buffer should be unmapped + read, TLS should be user readable. */ - const KMemoryPermission src_perm = static_cast(src_user ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelRead) : KMemoryPermission_UserRead); + const KMemoryPermission src_perm = static_cast(src_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelRead : KMemoryPermission_UserRead); /* Perform the fast part of the copy. */ R_TRY(src_page_table.CopyMemoryFromLinearToKernel(reinterpret_cast(dst_msg_ptr) + offset_words, fast_size, src_message_buffer + offset_words, @@ -753,7 +753,7 @@ namespace ams::kern { /* Perform the pointer data copy. */ const bool dst_heap = dst_user && dst_recv_list.IsToMessageBuffer(); const auto dst_state = dst_heap ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; - const KMemoryPermission dst_perm = static_cast(dst_heap ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite) : KMemoryPermission_UserReadWrite); + const KMemoryPermission dst_perm = static_cast(dst_heap ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite); R_TRY(dst_page_table.CopyMemoryFromUserToLinear(recv_pointer, recv_size, dst_state, dst_state, dst_perm, @@ -911,7 +911,7 @@ namespace ams::kern { const auto dst_state = dst_user ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; /* Determine the dst permission. User buffer should be unmapped + read, TLS should be user readable. */ - const KMemoryPermission dst_perm = static_cast(dst_user ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite) : KMemoryPermission_UserReadWrite); + const KMemoryPermission dst_perm = static_cast(dst_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite); /* Perform the fast part of the copy. */ R_TRY(dst_page_table.CopyMemoryFromKernelToLinear(dst_message_buffer + offset_words, fast_size, diff --git a/libraries/libmesosphere/source/kern_k_shared_memory.cpp b/libraries/libmesosphere/source/kern_k_shared_memory.cpp index 95d0dc401..c7850fb1d 100644 --- a/libraries/libmesosphere/source/kern_k_shared_memory.cpp +++ b/libraries/libmesosphere/source/kern_k_shared_memory.cpp @@ -37,7 +37,7 @@ namespace ams::kern { R_UNLESS(memory_reservation.Succeeded(), svc::ResultLimitReached()); /* Allocate the memory. */ - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(m_page_group), num_pages, 1, owner->GetAllocateOption())); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(m_page_group), num_pages, owner->GetAllocateOption())); /* Commit our reservation. */ memory_reservation.Commit(); diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index dece074ef..77582203c 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -39,18 +39,17 @@ namespace ams::kern { KPhysicalAddress KSystemControlBase::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) { const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize(); const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize(); - if (intended_dram_size * 2 <= real_dram_size) { + if (intended_dram_size * 2 < real_dram_size) { return base_address; } else { return base_address + ((real_dram_size - intended_dram_size) / 2); } } - void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address) { + void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out) { *out = { - .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax, - ._08 = 0, - .kern_address = GetInteger(kern_base_address), + .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax, + ._08 = 0, }; } @@ -78,7 +77,7 @@ namespace ams::kern { void KSystemControlBase::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { #if defined(ATMOSPHERE_ARCH_ARM64) - MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0>(core_id, entrypoint, arg)) == 0); + MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0, false>(core_id, entrypoint, arg)) == 0); #else AMS_INFINITE_LOOP(); #endif @@ -102,10 +101,10 @@ namespace ams::kern { /* Randomness for Initialization. */ void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) { - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { + if (AMS_UNLIKELY(!s_initialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; + s_initialized_random_generator = true; } for (size_t i = 0; i < count; ++i) { @@ -114,24 +113,41 @@ namespace ams::kern { } u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) { - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { + if (AMS_UNLIKELY(!s_initialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; + s_initialized_random_generator = true; } 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() { - /* Enable KTargetSystem. */ + /* Configure KTargetSystem. */ { - KTargetSystem::SetInitialized(); + /* 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); + } } /* Initialize random and resource limit. */ @@ -140,9 +156,9 @@ namespace ams::kern { void KSystemControlBase::InitializePhase1Base(u64 seed) { /* Initialize the rng, if we somehow haven't already. */ - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { + if (AMS_UNLIKELY(!s_initialized_random_generator)) { s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; + s_initialized_random_generator = true; } /* Initialize debug logging. */ diff --git a/libraries/libmesosphere/source/kern_k_system_resource.cpp b/libraries/libmesosphere/source/kern_k_system_resource.cpp index fc4876252..876d6129d 100644 --- a/libraries/libmesosphere/source/kern_k_system_resource.cpp +++ b/libraries/libmesosphere/source/kern_k_system_resource.cpp @@ -59,9 +59,7 @@ namespace ams::kern { memory_reservation.Commit(); /* Open reference to our resource limit. */ - if (m_resource_limit != nullptr) { - m_resource_limit->Open(); - } + m_resource_limit->Open(); /* Set ourselves as initialized. */ m_is_initialized = true; @@ -78,14 +76,11 @@ namespace ams::kern { /* Free our secure memory. */ KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool); - /* Clean up our resource usage. */ - if (m_resource_limit != nullptr) { - /* Release the memory reservation. */ - m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); + /* 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 74b39acd3..942e85b10 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -476,6 +476,10 @@ namespace ams::kern { m_parent->ClearRunningThread(this); } + /* Signal. */ + m_signaled = true; + KSynchronizationObject::NotifyAvailable(); + /* Call the on thread termination handler. */ KThreadContext::OnThreadTerminating(this); @@ -503,13 +507,6 @@ namespace ams::kern { cpu::SynchronizeCores(m_parent->GetPhysicalCoreMask()); } - /* Acquire the scheduler lock. */ - KScopedSchedulerLock sl; - - /* Signal. */ - m_signaled = true; - KSynchronizationObject::NotifyAvailable(); - /* Close the thread. */ this->Close(); } @@ -1331,7 +1328,7 @@ namespace ams::kern { this->StartTermination(); /* Register the thread as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitThread, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); } MESOSPHERE_PANIC("KThread::Exit() would return"); @@ -1438,10 +1435,7 @@ 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 9660d906d..cc80d9fbe 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -74,45 +74,43 @@ 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 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)); + /* Initialize the fixed-size slabheaps. */ 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)); + s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize); + s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize); /* 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)); - /* 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); + /* 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)); - /* 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); + s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap)); /* 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 160bb495d..14209eb1f 100644 --- a/libraries/libmesosphere/source/kern_main.cpp +++ b/libraries/libmesosphere/source/kern_main.cpp @@ -56,9 +56,8 @@ 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(), MinimumMemoryManagerAlignmentShifts); + Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize()); } /* Copy the Initial Process Binary to safe memory. */ @@ -116,9 +115,8 @@ namespace ams::kern { /* Perform more core-0 specific initialization. */ if (core_id == 0) { - /* Initialize the exit worker managers, so that threads and processes may exit cleanly. */ - Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_ExitThread).Initialize(KWorkerTaskManager::ExitWorkerPriority); - Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_ExitProcess).Initialize(KWorkerTaskManager::ExitWorkerPriority); + /* Initialize the exit worker manager, so that threads and processes may exit cleanly. */ + Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_Exit).Initialize(KWorkerTaskManager::ExitWorkerPriority); /* Setup so that we may sleep later, and reserve memory for secure applets. */ KSystemControl::InitializePhase2(); diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp index 2b495ad45..68eb61e84 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp @@ -41,22 +41,17 @@ 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, int64_t value, int64_t timeout_ns) { + Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { /* Validate input. */ - 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()); + 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()); /* Convert timeout from nanoseconds to ticks. */ s64 timeout; @@ -90,7 +85,7 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ - Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { + Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } @@ -100,7 +95,7 @@ namespace ams::kern::svc { /* ============================= 64From32 ABI ============================= */ - Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { + Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp index e93fbfd55..746eed6bb 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp @@ -37,7 +37,7 @@ namespace ams::kern::svc { R_SUCCEED(); } - Result QueryMemoryMapping(uintptr_t *out_address, size_t *out_size, uint64_t phys_addr, size_t size) { + Result QueryIoMapping(uintptr_t *out_address, size_t *out_size, uint64_t phys_addr, size_t size) { /* Declare variables we'll populate. */ KProcessAddress found_address = Null; size_t found_size = 0; @@ -125,15 +125,15 @@ namespace ams::kern::svc { R_RETURN(QueryPhysicalAddress(out_info, address)); } - Result QueryMemoryMapping64(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { + Result QueryIoMapping64(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); static_assert(sizeof(*out_size) == sizeof(size_t)); - R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + R_RETURN(QueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } Result LegacyQueryIoMapping64(ams::svc::Address *out_address, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); - R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); + R_RETURN(QueryIoMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); } /* ============================= 64From32 ABI ============================= */ @@ -150,15 +150,15 @@ namespace ams::kern::svc { R_SUCCEED(); } - Result QueryMemoryMapping64From32(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { + Result QueryIoMapping64From32(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); static_assert(sizeof(*out_size) == sizeof(size_t)); - R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + R_RETURN(QueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } Result LegacyQueryIoMapping64From32(ams::svc::Address *out_address, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); - R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); + R_RETURN(QueryIoMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp index c6ffb5e4c..62997b50b 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp @@ -102,11 +102,7 @@ namespace ams::kern::svc { R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); /* Invalidate the cache. */ - if (process.GetPointerUnsafe() == GetCurrentProcessPointer()) { - R_TRY(process->GetPageTable().InvalidateCurrentProcessDataCache(address, size)); - } else { - R_TRY(process->GetPageTable().InvalidateProcessDataCache(address, size)); - } + R_TRY(process->GetPageTable().InvalidateProcessDataCache(address, size)); R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp index 986654ce4..369885355 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp @@ -24,9 +24,6 @@ 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()); @@ -35,8 +32,9 @@ namespace ams::kern::svc { ON_SCOPE_EXIT { process->Close(); }; /* Check that the debugging is allowed. */ - const bool allowable = process->IsPermittedDebug() || GetCurrentProcess().CanForceDebug() || GetCurrentProcess().CanForceDebugProd(); - R_UNLESS(allowable, svc::ResultInvalidState()); + if (!process->IsPermittedDebug()) { + R_UNLESS(GetCurrentProcess().CanForceDebug(), svc::ResultInvalidState()); + } /* Disallow debugging one's own processs, to prevent softlocks. */ R_UNLESS(process != GetCurrentProcessPointer(), svc::ResultInvalidState()); @@ -94,9 +92,6 @@ 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()); @@ -169,9 +164,6 @@ 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()); @@ -228,9 +220,6 @@ 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()); @@ -272,9 +261,6 @@ 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()); @@ -320,9 +306,6 @@ 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 ec41ef59a..3c107b590 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -106,9 +106,6 @@ namespace ams::kern::svc { *out = 0; } break; - case ams::svc::InfoType_AliasRegionExtraSize: - *out = process->GetPageTable().GetAliasRegionExtraSize(); - break; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } @@ -137,7 +134,6 @@ namespace ams::kern::svc { case ams::svc::InfoType_UsedNonSystemMemorySize: case ams::svc::InfoType_IsApplication: case ams::svc::InfoType_FreeThreadCount: - case ams::svc::InfoType_AliasRegionExtraSize: { /* These info types don't support non-zero subtypes. */ R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); @@ -314,19 +310,6 @@ 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_insecure_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp index c0262b5c1..c358bff2d 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp @@ -21,7 +21,7 @@ namespace ams::kern::svc { namespace { - Result MapInsecurePhysicalMemory(uintptr_t address, size_t size) { + Result MapInsecureMemory(uintptr_t address, size_t size) { /* Validate the address/size. */ R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); R_UNLESS(size > 0, svc::ResultInvalidSize()); @@ -33,10 +33,10 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Insecure), svc::ResultInvalidMemoryRegion()); /* Map the insecure memory. */ - R_RETURN(pt.MapInsecurePhysicalMemory(address, size)); + R_RETURN(pt.MapInsecureMemory(address, size)); } - Result UnmapInsecurePhysicalMemory(uintptr_t address, size_t size) { + Result UnmapInsecureMemory(uintptr_t address, size_t size) { /* Validate the address/size. */ R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); R_UNLESS(size > 0, svc::ResultInvalidSize()); @@ -48,29 +48,29 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Insecure), svc::ResultInvalidMemoryRegion()); /* Map the insecure memory. */ - R_RETURN(pt.UnmapInsecurePhysicalMemory(address, size)); + R_RETURN(pt.UnmapInsecureMemory(address, size)); } } /* ============================= 64 ABI ============================= */ - Result MapInsecurePhysicalMemory64(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(MapInsecurePhysicalMemory(address, size)); + Result MapInsecureMemory64(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(MapInsecureMemory(address, size)); } - Result UnmapInsecurePhysicalMemory64(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(UnmapInsecurePhysicalMemory(address, size)); + Result UnmapInsecureMemory64(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(UnmapInsecureMemory(address, size)); } /* ============================= 64From32 ABI ============================= */ - Result MapInsecurePhysicalMemory64From32(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(MapInsecurePhysicalMemory(address, size)); + Result MapInsecureMemory64From32(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(MapInsecureMemory(address, size)); } - Result UnmapInsecurePhysicalMemory64From32(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(UnmapInsecurePhysicalMemory(address, size)); + Result UnmapInsecureMemory64From32(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(UnmapInsecureMemory(address, size)); } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp b/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp index a5d132e61..ffa65f723 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp @@ -127,7 +127,7 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Verify that the mapping is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, ams::svc::MemoryState_Io), svc::ResultInvalidMemoryRegion()); + R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Io), svc::ResultInvalidMemoryRegion()); /* Validate the map permission. */ R_UNLESS(IsValidIoRegionPermission(map_perm), svc::ResultInvalidNewMemoryPermission()); @@ -156,7 +156,7 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Verify that the mapping is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, ams::svc::MemoryState_Io), svc::ResultInvalidMemoryRegion()); + R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Io), svc::ResultInvalidMemoryRegion()); /* Get the io region. */ KScopedAutoObject io_region = GetCurrentProcess().GetHandleTable().GetObject(io_region_handle); diff --git a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp index a67b581cb..06393a3f7 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp @@ -143,7 +143,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the message buffer. */ + /* Lock the mesage buffer. */ R_TRY(page_table.LockForIpcUserBuffer(nullptr, message, buffer_size)); { @@ -186,7 +186,7 @@ namespace ams::kern::svc { /* Commit our reservation. */ event_reservation.Commit(); - /* At end of scope, kill the standing event references. */ + /* At end of scope, kill the standing references to the sub events. */ ON_SCOPE_EXIT { event->GetReadableEvent().Close(); event->Close(); @@ -215,7 +215,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the message buffer. */ + /* Lock the mesage buffer. */ R_TRY(page_table.LockForIpcUserBuffer(nullptr, message, buffer_size)); /* Ensure that if we fail and aren't terminating that we unlock the user buffer. */ @@ -242,7 +242,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the message buffer, getting its physical address. */ + /* Lock the mesage buffer, getting its physical address. */ KPhysicalAddress message_paddr; R_TRY(page_table.LockForIpcUserBuffer(std::addressof(message_paddr), message, buffer_size)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp index 95173a0db..a6994fae4 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp @@ -58,13 +58,10 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Validate the attribute and mask. */ - constexpr u32 SupportedMask = ams::svc::MemoryAttribute_Uncached | ams::svc::MemoryAttribute_PermissionLocked; + constexpr u32 SupportedMask = ams::svc::MemoryAttribute_Uncached; R_UNLESS((mask | attr) == mask, svc::ResultInvalidCombination()); R_UNLESS((mask | attr | SupportedMask) == SupportedMask, svc::ResultInvalidCombination()); - /* Check that permission locked is either being set or not masked. */ - R_UNLESS((mask & ams::svc::MemoryAttribute_PermissionLocked) == (attr & ams::svc::MemoryAttribute_PermissionLocked), svc::ResultInvalidCombination()); - /* Validate that the region is in range for the current process. */ auto &page_table = GetCurrentProcess().GetPageTable(); R_UNLESS(page_table.Contains(address, size), svc::ResultInvalidCurrentMemory()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp index e2237877d..fc5414905 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp @@ -48,11 +48,10 @@ namespace ams::kern::svc { Result MapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - 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()); + 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()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); @@ -70,11 +69,10 @@ namespace ams::kern::svc { Result UnmapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - 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()); + 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()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); diff --git a/libraries/libmesosphere/source/svc/kern_svc_port.cpp b/libraries/libmesosphere/source/svc/kern_svc_port.cpp index 1ac5803d2..d4520d287 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_port.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_port.cpp @@ -96,7 +96,7 @@ namespace ams::kern::svc { /* Add the client to the handle table. */ R_TRY(handle_table.Add(out_client, std::addressof(port->GetClientPort()))); - /* Ensure that we maintain a clean handle state on exit. */ + /* Ensure that we maintaing a clean handle state on exit. */ ON_RESULT_FAILURE { handle_table.Remove(*out_client); }; /* Add the server to the handle table. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 6e516a51f..e73e5829c 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -71,9 +71,6 @@ 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()); @@ -109,13 +106,12 @@ 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(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(32, KAddressSpaceInfo::Type_MapSmall); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(32, KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -124,8 +120,8 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - 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_start = KAddressSpaceInfo::GetAddressSpaceStart(36, KAddressSpaceInfo::Type_MapSmall); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(36, KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -134,10 +130,10 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - 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_start = KAddressSpaceInfo::GetAddressSpaceStart(39, KAddressSpaceInfo::Type_Map39Bit); + map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Map39Bit); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Heap); } break; default: @@ -166,22 +162,11 @@ namespace ams::kern::svc { /* Check that the number of extra resource pages is >= 0. */ R_UNLESS(params.system_resource_num_pages >= 0, svc::ResultInvalidSize()); - /* Validate that the alias region extra size is allowed, if enabled. */ - if (params.flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { - /* Check that we have a 64-bit address space. */ - R_UNLESS((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace64Bit, svc::ResultInvalidState()); - - /* Check that the system resource page count is non-zero. */ - R_UNLESS(params.system_resource_num_pages > 0, svc::ResultInvalidState()); - - /* Check that debug mode is enabled. */ - R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultInvalidState()); - } - /* Convert to sizes. */ 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; @@ -296,9 +281,7 @@ 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. */ - 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()); + R_UNLESS(main_thread_stack_size == static_cast(main_thread_stack_size), svc::ResultOutOfMemory()); /* Get the target process. */ KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject(process_handle); @@ -316,7 +299,7 @@ namespace ams::kern::svc { process->SetIdealCoreId(core_id); /* Run the process. */ - R_RETURN(process->Run(priority, static_cast(aligned_stack_size))); + R_RETURN(process->Run(priority, static_cast(main_thread_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 41420ca06..91d799d78 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp @@ -27,7 +27,6 @@ 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 6f74dd145..99c8c37a8 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp @@ -217,9 +217,6 @@ 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()); @@ -228,34 +225,30 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory()); } - /* 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)); + 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)); } else { - /* Only allow getting as a process (or global) if the caller does not have ForceDebugProd. */ - R_UNLESS(!GetCurrentProcess().CanForceDebugProd(), svc::ResultInvalidHandle()); + /* 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()); - /* 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/ams_exosphere_api.hpp b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp index 2712b2b50..84cdfe9a9 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp @@ -25,7 +25,6 @@ namespace ams::exosphere { void ForceRebootToRcm(); void ForceRebootToIramPayload(); void ForceRebootToFatalError(); - void ForceRebootByPmic(); void ForceShutdown(); bool IsRcmBugPatched(); 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 ca1c5cb5d..cd20d43a7 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(21, ro, Main); + AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); /* gpio. */ AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler); @@ -171,8 +171,6 @@ 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 a103aae83..146b17dd5 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 a6a6d5f55..ef867f14c 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -35,930 +35,819 @@ HANDLER(FieldType_NumericU8, 12) \ HANDLER(FieldType_NumericI16, 13) \ HANDLER(FieldType_NumericI8, 14) \ - HANDLER(FieldType_I8Array, 15) + HANDLER(FieldType_I8Array, 15) \ #define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \ - HANDLER(Test, 0 ) \ - HANDLER(ErrorInfo, 1 ) \ - HANDLER(ConnectionStatusInfo, 2 ) \ - HANDLER(NetworkInfo, 3 ) \ - HANDLER(NXMacAddressInfo, 4 ) \ - HANDLER(StealthNetworkInfo, 5 ) \ - HANDLER(LimitHighCapacityInfo, 6 ) \ - HANDLER(NATTypeInfo, 7 ) \ - HANDLER(WirelessAPMacAddressInfo, 8 ) \ - HANDLER(GlobalIPAddressInfo, 9 ) \ - HANDLER(EnableWirelessInterfaceInfo, 10 ) \ - HANDLER(EnableWifiInfo, 11 ) \ - HANDLER(EnableBluetoothInfo, 12 ) \ - HANDLER(EnableNFCInfo, 13 ) \ - HANDLER(NintendoZoneSSIDListVersionInfo, 14 ) \ - HANDLER(LANAdapterMacAddressInfo, 15 ) \ - HANDLER(ApplicationInfo, 16 ) \ - HANDLER(OccurrenceInfo, 17 ) \ - HANDLER(ProductModelInfo, 18 ) \ - HANDLER(CurrentLanguageInfo, 19 ) \ - HANDLER(UseNetworkTimeProtocolInfo, 20 ) \ - HANDLER(TimeZoneInfo, 21 ) \ - HANDLER(ControllerFirmwareInfo, 22 ) \ - HANDLER(VideoOutputInfo, 23 ) \ - HANDLER(NANDFreeSpaceInfo, 24 ) \ - HANDLER(SDCardFreeSpaceInfo, 25 ) \ - HANDLER(ScreenBrightnessInfo, 26 ) \ - HANDLER(AudioFormatInfo, 27 ) \ - HANDLER(MuteOnHeadsetUnpluggedInfo, 28 ) \ - HANDLER(NumUserRegisteredInfo, 29 ) \ - HANDLER(DataDeletionInfo, 30 ) \ - HANDLER(ControllerVibrationInfo, 31 ) \ - HANDLER(LockScreenInfo, 32 ) \ - HANDLER(InternalBatteryLotNumberInfo, 33 ) \ - HANDLER(LeftControllerSerialNumberInfo, 34 ) \ - HANDLER(RightControllerSerialNumberInfo, 35 ) \ - HANDLER(NotificationInfo, 36 ) \ - HANDLER(TVInfo, 37 ) \ - HANDLER(SleepInfo, 38 ) \ - HANDLER(ConnectionInfo, 39 ) \ - HANDLER(NetworkErrorInfo, 40 ) \ - HANDLER(FileAccessPathInfo, 41 ) \ - HANDLER(GameCardCIDInfo, 42 ) \ - HANDLER(NANDCIDInfoDeprecated, 43 ) \ - HANDLER(MicroSDCIDInfoDeprecated, 44 ) \ - HANDLER(NANDSpeedModeInfo, 45 ) \ - HANDLER(MicroSDSpeedModeInfo, 46 ) \ - HANDLER(GameCardSpeedModeInfo, 47 ) \ - HANDLER(UserAccountInternalIDInfo, 48 ) \ - HANDLER(NetworkServiceAccountInternalIDInfo, 49 ) \ - HANDLER(NintendoAccountInternalIDInfo, 50 ) \ - HANDLER(USB3AvailableInfo, 51 ) \ - HANDLER(CallStackInfo, 52 ) \ - HANDLER(SystemStartupLogInfo, 53 ) \ - HANDLER(RegionSettingInfo, 54 ) \ - HANDLER(NintendoZoneConnectedInfo, 55 ) \ - HANDLER(ForceSleepInfo, 56 ) \ - HANDLER(ChargerInfo, 57 ) \ - HANDLER(RadioStrengthInfo, 58 ) \ - HANDLER(ErrorInfoAuto, 59 ) \ - HANDLER(AccessPointInfo, 60 ) \ - HANDLER(ErrorInfoDefaults, 61 ) \ - HANDLER(SystemPowerStateInfo, 62 ) \ - HANDLER(PerformanceInfo, 63 ) \ - HANDLER(ThrottlingInfo, 64 ) \ - HANDLER(GameCardErrorInfo, 65 ) \ - HANDLER(EdidInfo, 66 ) \ - HANDLER(ThermalInfo, 67 ) \ - HANDLER(CradleFirmwareInfo, 68 ) \ - HANDLER(RunningApplicationInfo, 69 ) \ - HANDLER(RunningAppletInfo, 70 ) \ - HANDLER(FocusedAppletHistoryInfo, 71 ) \ - HANDLER(CompositorInfo, 72 ) \ - HANDLER(BatteryChargeInfo, 73 ) \ - HANDLER(NANDExtendedCsdDeprecated, 74 ) \ - HANDLER(NANDPatrolInfo, 75 ) \ - HANDLER(NANDErrorInfo, 76 ) \ - HANDLER(NANDDriverLog, 77 ) \ - HANDLER(SdCardSizeSpec, 78 ) \ - HANDLER(SdCardErrorInfo, 79 ) \ - HANDLER(SdCardDriverLog , 80 ) \ - HANDLER(FsProxyErrorInfo, 81 ) \ - HANDLER(SystemAppletSceneInfo, 82 ) \ - HANDLER(VideoInfo, 83 ) \ - HANDLER(GpuErrorInfo, 84 ) \ - HANDLER(PowerClockInfo, 85 ) \ - HANDLER(AdspErrorInfo, 86 ) \ - HANDLER(NvDispDeviceInfo, 87 ) \ - HANDLER(NvDispDcWindowInfo, 88 ) \ - HANDLER(NvDispDpModeInfo, 89 ) \ - HANDLER(NvDispDpLinkSpec, 90 ) \ - HANDLER(NvDispDpLinkStatus, 91 ) \ - HANDLER(NvDispDpHdcpInfo, 92 ) \ - HANDLER(NvDispDpAuxCecInfo, 93 ) \ - HANDLER(NvDispDcInfo, 94 ) \ - HANDLER(NvDispDsiInfo, 95 ) \ - HANDLER(NvDispErrIDInfo, 96 ) \ - HANDLER(SdCardMountInfo, 97 ) \ - HANDLER(RetailInteractiveDisplayInfo, 98 ) \ - HANDLER(CompositorStateInfo, 99 ) \ - HANDLER(CompositorLayerInfo, 100 ) \ - HANDLER(CompositorDisplayInfo, 101 ) \ - HANDLER(CompositorHWCInfo, 102 ) \ - HANDLER(MonitorCapability, 103 ) \ - HANDLER(ErrorReportSharePermissionInfo, 104 ) \ - HANDLER(MultimediaInfo, 105 ) \ - HANDLER(ConnectedControllerInfo, 106 ) \ - HANDLER(FsMemoryInfo, 107 ) \ - HANDLER(UserClockContextInfo, 108 ) \ - HANDLER(NetworkClockContextInfo, 109 ) \ - HANDLER(AcpGeneralSettingsInfo, 110 ) \ - HANDLER(AcpPlayLogSettingsInfo, 111 ) \ - HANDLER(AcpAocSettingsInfo, 112 ) \ - HANDLER(AcpBcatSettingsInfo, 113 ) \ - HANDLER(AcpStorageSettingsInfo, 114 ) \ - HANDLER(AcpRatingSettingsInfo, 115 ) \ - HANDLER(MonitorSettings, 116 ) \ - HANDLER(RebootlessSystemUpdateVersionInfo, 117 ) \ - HANDLER(NifmConnectionTestInfo, 118 ) \ - HANDLER(PcieLoggedStateInfo, 119 ) \ - HANDLER(NetworkSecurityCertificateInfo, 120 ) \ - HANDLER(AcpNeighborDetectionInfo, 121 ) \ - HANDLER(GpuCrashInfo, 122 ) \ - HANDLER(UsbStateInfo, 123 ) \ - HANDLER(NvHostErrInfo, 124 ) \ - HANDLER(RunningUlaInfo, 125 ) \ - HANDLER(InternalPanelInfo, 126 ) \ - HANDLER(ResourceLimitLimitInfo, 127 ) \ - HANDLER(ResourceLimitPeakInfo, 128 ) \ - HANDLER(TouchScreenInfo, 129 ) \ - HANDLER(AcpUserAccountSettingsInfo, 130 ) \ - HANDLER(AudioDeviceInfo, 131 ) \ - HANDLER(AbnormalWakeInfo, 132 ) \ - HANDLER(ServiceProfileInfo, 133 ) \ - HANDLER(BluetoothAudioInfo, 134 ) \ - HANDLER(BluetoothPairingCountInfo, 135 ) \ - HANDLER(FsProxyErrorInfo2, 136 ) \ - HANDLER(BuiltInWirelessOUIInfo, 137 ) \ - HANDLER(WirelessAPOUIInfo, 138 ) \ - HANDLER(EthernetAdapterOUIInfo, 139 ) \ - HANDLER(NANDTypeInfoDeprecated, 140 ) \ - HANDLER(MicroSDTypeInfo, 141 ) \ - 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) \ + HANDLER(Test, 0 ) \ + HANDLER(ErrorInfo, 1 ) \ + HANDLER(ConnectionStatusInfo, 2 ) \ + HANDLER(NetworkInfo, 3 ) \ + HANDLER(NXMacAddressInfo, 4 ) \ + HANDLER(StealthNetworkInfo, 5 ) \ + HANDLER(LimitHighCapacityInfo, 6 ) \ + HANDLER(NATTypeInfo, 7 ) \ + HANDLER(WirelessAPMacAddressInfo, 8 ) \ + HANDLER(GlobalIPAddressInfo, 9 ) \ + HANDLER(EnableWirelessInterfaceInfo, 10 ) \ + HANDLER(EnableWifiInfo, 11 ) \ + HANDLER(EnableBluetoothInfo, 12 ) \ + HANDLER(EnableNFCInfo, 13 ) \ + HANDLER(NintendoZoneSSIDListVersionInfo, 14 ) \ + HANDLER(LANAdapterMacAddressInfo, 15 ) \ + HANDLER(ApplicationInfo, 16 ) \ + HANDLER(OccurrenceInfo, 17 ) \ + HANDLER(ProductModelInfo, 18 ) \ + HANDLER(CurrentLanguageInfo, 19 ) \ + HANDLER(UseNetworkTimeProtocolInfo, 20 ) \ + HANDLER(TimeZoneInfo, 21 ) \ + HANDLER(ControllerFirmwareInfo, 22 ) \ + HANDLER(VideoOutputInfo, 23 ) \ + HANDLER(NANDFreeSpaceInfo, 24 ) \ + HANDLER(SDCardFreeSpaceInfo, 25 ) \ + HANDLER(ScreenBrightnessInfo, 26 ) \ + HANDLER(AudioFormatInfo, 27 ) \ + HANDLER(MuteOnHeadsetUnpluggedInfo, 28 ) \ + HANDLER(NumUserRegisteredInfo, 29 ) \ + HANDLER(DataDeletionInfo, 30 ) \ + HANDLER(ControllerVibrationInfo, 31 ) \ + HANDLER(LockScreenInfo, 32 ) \ + HANDLER(InternalBatteryLotNumberInfo, 33 ) \ + HANDLER(LeftControllerSerialNumberInfo, 34 ) \ + HANDLER(RightControllerSerialNumberInfo, 35 ) \ + HANDLER(NotificationInfo, 36 ) \ + HANDLER(TVInfo, 37 ) \ + HANDLER(SleepInfo, 38 ) \ + HANDLER(ConnectionInfo, 39 ) \ + HANDLER(NetworkErrorInfo, 40 ) \ + HANDLER(FileAccessPathInfo, 41 ) \ + HANDLER(GameCardCIDInfo, 42 ) \ + HANDLER(NANDCIDInfo, 43 ) \ + HANDLER(MicroSDCIDInfo, 44 ) \ + HANDLER(NANDSpeedModeInfo, 45 ) \ + HANDLER(MicroSDSpeedModeInfo, 46 ) \ + HANDLER(GameCardSpeedModeInfo, 47 ) \ + HANDLER(UserAccountInternalIDInfo, 48 ) \ + HANDLER(NetworkServiceAccountInternalIDInfo, 49 ) \ + HANDLER(NintendoAccountInternalIDInfo, 50 ) \ + HANDLER(USB3AvailableInfo, 51 ) \ + HANDLER(CallStackInfo, 52 ) \ + HANDLER(SystemStartupLogInfo, 53 ) \ + HANDLER(RegionSettingInfo, 54 ) \ + HANDLER(NintendoZoneConnectedInfo, 55 ) \ + HANDLER(ForceSleepInfo, 56 ) \ + HANDLER(ChargerInfo, 57 ) \ + HANDLER(RadioStrengthInfo, 58 ) \ + HANDLER(ErrorInfoAuto, 59 ) \ + HANDLER(AccessPointInfo, 60 ) \ + HANDLER(ErrorInfoDefaults, 61 ) \ + HANDLER(SystemPowerStateInfo, 62 ) \ + HANDLER(PerformanceInfo, 63 ) \ + HANDLER(ThrottlingInfo, 64 ) \ + HANDLER(GameCardErrorInfo, 65 ) \ + HANDLER(EdidInfo, 66 ) \ + HANDLER(ThermalInfo, 67 ) \ + HANDLER(CradleFirmwareInfo, 68 ) \ + HANDLER(RunningApplicationInfo, 69 ) \ + HANDLER(RunningAppletInfo, 70 ) \ + HANDLER(FocusedAppletHistoryInfo, 71 ) \ + HANDLER(CompositorInfo, 72 ) \ + HANDLER(BatteryChargeInfo, 73 ) \ + HANDLER(NANDExtendedCsd, 74 ) \ + HANDLER(NANDPatrolInfo, 75 ) \ + HANDLER(NANDErrorInfo, 76 ) \ + HANDLER(NANDDriverLog, 77 ) \ + HANDLER(SdCardSizeSpec, 78 ) \ + HANDLER(SdCardErrorInfo, 79 ) \ + HANDLER(SdCardDriverLog , 80 ) \ + HANDLER(FsProxyErrorInfo, 81 ) \ + HANDLER(SystemAppletSceneInfo, 82 ) \ + HANDLER(VideoInfo, 83 ) \ + HANDLER(GpuErrorInfo, 84 ) \ + HANDLER(PowerClockInfo, 85 ) \ + HANDLER(AdspErrorInfo, 86 ) \ + HANDLER(NvDispDeviceInfo, 87 ) \ + HANDLER(NvDispDcWindowInfo, 88 ) \ + HANDLER(NvDispDpModeInfo, 89 ) \ + HANDLER(NvDispDpLinkSpec, 90 ) \ + HANDLER(NvDispDpLinkStatus, 91 ) \ + HANDLER(NvDispDpHdcpInfo, 92 ) \ + HANDLER(NvDispDpAuxCecInfo, 93 ) \ + HANDLER(NvDispDcInfo, 94 ) \ + HANDLER(NvDispDsiInfo, 95 ) \ + HANDLER(NvDispErrIDInfo, 96 ) \ + HANDLER(SdCardMountInfo, 97 ) \ + HANDLER(RetailInteractiveDisplayInfo, 98 ) \ + HANDLER(CompositorStateInfo, 99 ) \ + HANDLER(CompositorLayerInfo, 100) \ + HANDLER(CompositorDisplayInfo, 101) \ + HANDLER(CompositorHWCInfo, 102) \ + HANDLER(MonitorCapability, 103) \ + HANDLER(ErrorReportSharePermissionInfo, 104) \ + HANDLER(MultimediaInfo, 105) \ + HANDLER(ConnectedControllerInfo, 106) \ + HANDLER(FsMemoryInfo, 107) \ + HANDLER(UserClockContextInfo, 108) \ + HANDLER(NetworkClockContextInfo, 109) \ + HANDLER(AcpGeneralSettingsInfo, 110) \ + HANDLER(AcpPlayLogSettingsInfo, 111) \ + HANDLER(AcpAocSettingsInfo, 112) \ + HANDLER(AcpBcatSettingsInfo, 113) \ + HANDLER(AcpStorageSettingsInfo, 114) \ + HANDLER(AcpRatingSettingsInfo, 115) \ + HANDLER(MonitorSettings, 116) \ + HANDLER(RebootlessSystemUpdateVersionInfo, 117) \ + HANDLER(NifmConnectionTestInfo, 118) \ + HANDLER(PcieLoggedStateInfo, 119) \ + HANDLER(NetworkSecurityCertificateInfo, 120) \ + HANDLER(AcpNeighborDetectionInfo, 121) \ + HANDLER(GpuCrashInfo, 122) \ + HANDLER(UsbStateInfo, 123) \ + HANDLER(NvHostErrInfo, 124) \ + HANDLER(RunningUlaInfo, 125) \ + HANDLER(InternalPanelInfo, 126) \ + HANDLER(ResourceLimitLimitInfo, 127) \ + HANDLER(ResourceLimitPeakInfo, 128) \ + HANDLER(TouchScreenInfo, 129) \ + HANDLER(AcpUserAccountSettingsInfo, 130) \ + HANDLER(AudioDeviceInfo, 131) \ + HANDLER(AbnormalWakeInfo, 132) \ + HANDLER(ServiceProfileInfo, 133) \ + HANDLER(BluetoothAudioInfo, 134) \ + HANDLER(BluetoothPairingCountInfo, 135) \ + HANDLER(FsProxyErrorInfo2, 136) \ + HANDLER(BuiltInWirelessOUIInfo, 137) \ + HANDLER(WirelessAPOUIInfo, 138) \ + HANDLER(EthernetAdapterOUIInfo, 139) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ - HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ - HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ - HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(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 ) \ - HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(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 ) \ - HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimitDeprecated, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfigurationDeprecated, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizModeDeprecated, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPathDeprecated, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequestedDeprecated, 189, BatteryChargeInfo, FieldType_Bool, 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 ) \ - HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegistersDeprecated, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsrDeprecated, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegistersDeprecated, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - 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(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(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(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltagesDeprecated, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, 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 ) \ - HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ - HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ - HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ - HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ - HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ - HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ - HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ - HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(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 ) \ - HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - 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(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 ) \ - HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeControlResult, 670, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatErrorNumber, 671, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeErrorNumber, 672, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatSafeControlResult, 673, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - 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(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(WlanChipResetTriggered, 735, WlanInfo, FieldType_Bool, 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 ) \ - HANDLER(HizMode, 1003, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 1004, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 1005, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 1006, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 1007, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 1008, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - 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(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 ) \ + HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ + HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ + HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ + HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ + HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ + HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ + HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ + HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + 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(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 3d31b2c42..3582448e1 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -34,6 +34,7 @@ namespace ams::erpt { enum CategoryId { AMS_ERPT_FOREACH_CATEGORY(GENERATE_ENUM) + CategoryId_Count, }; #undef GENERATE_ENUM @@ -42,6 +43,7 @@ namespace ams::erpt { enum FieldId { AMS_ERPT_FOREACH_FIELD(GENERATE_ENUM) + FieldId_Count, }; #undef GENERATE_ENUM @@ -109,14 +111,6 @@ namespace ams::erpt { static_assert(util::is_pod::value); static_assert(sizeof(ReportFlagSet) == sizeof(u32)); - struct CreateReportOptionFlag { - using SubmitFsInfo = util::BitFlagSet::Flag<0>; - }; - - using CreateReportOptionFlagSet = util::BitFlagSet; - static_assert(util::is_pod::value); - static_assert(sizeof(CreateReportOptionFlagSet) == sizeof(u32)); - struct ReportInfo { ReportType type; ReportId id; 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 a4fcc4dc6..f2917690f 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,28 +20,24 @@ #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, 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) +#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, 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), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 11, 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), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_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 e75bfb341..e8ed06310 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,16 +17,13 @@ #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, 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) - +#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) AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp index 348f3cb5f..2b1ec9830 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp @@ -58,98 +58,28 @@ namespace ams::erpt::srv { }; #undef STRINGIZE_HANDLER - #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) CategoryId_##CATEGORY, - constexpr inline const CategoryId FieldIndexToCategoryMap[] = { + #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = CategoryId_##CATEGORY, + constexpr inline const CategoryId FieldToCategoryMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_CATEGORY) }; #undef GET_FIELD_CATEGORY - #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) TYPE, - constexpr inline const FieldType FieldIndexToTypeMap[] = { + #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = TYPE, + constexpr inline const FieldType FieldToTypeMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_TYPE) }; #undef GET_FIELD_TYPE - #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) FLAG, - constexpr inline const FieldFlag FieldIndexToFlagMap[] = { + #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = FLAG, + constexpr inline const FieldFlag FieldToFlagMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_FLAG) }; #undef GET_FIELD_FLAG - #define GET_FIELD_ID(FIELD, ...) FieldId_##FIELD, - constexpr inline const FieldId FieldIndexToFieldIdMap[] = { - AMS_ERPT_FOREACH_FIELD(GET_FIELD_ID) - }; - #undef GET_FIELD_ID - - #define GET_CATEGORY_ID(CATEGORY, ...) CategoryId_##CATEGORY, - constexpr inline const CategoryId CategoryIndexToCategoryIdMap[] = { - AMS_ERPT_FOREACH_CATEGORY(GET_CATEGORY_ID) - }; - #undef GET_CATEGORY_ID - - constexpr util::optional FindFieldIndex(FieldId id) { - if (std::is_constant_evaluated()) { - for (size_t i = 0; i < util::size(FieldIndexToFieldIdMap); ++i) { - if (FieldIndexToFieldIdMap[i] == id) { - return i; - } - } - - return util::nullopt; - } else { - if (const auto it = std::lower_bound(std::begin(FieldIndexToFieldIdMap), std::end(FieldIndexToFieldIdMap), id); it != std::end(FieldIndexToFieldIdMap) && *it == id) { - return std::distance(FieldIndexToFieldIdMap, it); - } else { - return util::nullopt; - } - } - } - - constexpr util::optional FindCategoryIndex(CategoryId id) { - if (std::is_constant_evaluated()) { - for (size_t i = 0; i < util::size(CategoryIndexToCategoryIdMap); ++i) { - if (CategoryIndexToCategoryIdMap[i] == id) { - return i; - } - } - - return util::nullopt; - } else { - if (const auto it = std::lower_bound(std::begin(CategoryIndexToCategoryIdMap), std::end(CategoryIndexToCategoryIdMap), id); it != std::end(CategoryIndexToCategoryIdMap) && *it == id) { - return std::distance(CategoryIndexToCategoryIdMap, it); - } else { - return util::nullopt; - } - } - } - - constexpr inline CategoryId ConvertFieldToCategory(FieldId id) { - const auto index = FindFieldIndex(id); - AMS_ASSERT(index.has_value()); - return FieldIndexToCategoryMap[index.value()]; - } - - constexpr inline FieldType ConvertFieldToType(FieldId id) { - const auto index = FindFieldIndex(id); - AMS_ASSERT(index.has_value()); - return FieldIndexToTypeMap[index.value()]; - } - - constexpr inline FieldFlag ConvertFieldToFlag(FieldId id) { - const auto index = FindFieldIndex(id); - AMS_ASSERT(index.has_value()); - return FieldIndexToFlagMap[index.value()]; - } - constexpr inline ReportFlagSet MakeNoReportFlags() { return util::MakeBitFlagSet<32, ReportFlag>(); } - constexpr inline CreateReportOptionFlagSet MakeNoCreateReportOptionFlags() { - return util::MakeBitFlagSet<32, CreateReportOptionFlag>(); - } - constexpr inline AttachmentFlagSet MakeNoAttachmentFlags() { return util::MakeBitFlagSet<32, AttachmentFlag>(); } diff --git a/libraries/libstratosphere/include/stratosphere/fat.hpp b/libraries/libstratosphere/include/stratosphere/fat.hpp deleted file mode 100644 index 995267a2a..000000000 --- a/libraries/libstratosphere/include/stratosphere/fat.hpp +++ /dev/null @@ -1,17 +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 . - */ -#pragma once -#include \ No newline at end of file diff --git a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp deleted file mode 100644 index 46212a109..000000000 --- a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp +++ /dev/null @@ -1,55 +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 . - */ -#pragma once -#include - -namespace ams::fat { - - constexpr inline size_t FatErrorNameMaxLength = 0x10; - - struct FatError { - int error; - int extra_error; - int drive_id; - char name[FatErrorNameMaxLength]; - u8 reserved[4]; - }; - static_assert(sizeof(FatError) == 0x20); - static_assert(util::is_pod::value); - - struct FatReportInfo1 { - u16 open_file_peak_count; - u16 open_directory_peak_count; - }; - static_assert(sizeof(FatReportInfo1) == 4); - static_assert(util::is_pod::value); - - struct FatReportInfo2 { - u16 open_unique_file_entry_peak_count; - u16 open_unique_directory_entry_peak_count; - }; - static_assert(sizeof(FatReportInfo2) == 4); - static_assert(util::is_pod::value); - - struct FatSafeInfo { - u32 result; - u32 error_number; - u32 safe_error_number; - }; - static_assert(sizeof(FatSafeInfo) == 12); - static_assert(util::is_pod::value); - -} diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 9c3414051..7aafab832 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -51,11 +51,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -65,7 +63,6 @@ #include #include #include -#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp index 1bc47d4b2..dd5e5b33d 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, ncm::StorageId storage_id); + Result MountCode(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); + 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); } diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp deleted file mode 100644 index 06044631e..000000000 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp +++ /dev/null @@ -1,58 +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 . - */ -#pragma once -#include -#include - -namespace ams::fs { - - struct StorageErrorInfo { - u32 num_activation_failures; - u32 num_activation_error_corrections; - u32 num_read_write_failures; - u32 num_read_write_error_corrections; - }; - static_assert(sizeof(StorageErrorInfo) == 0x10); - static_assert(util::is_pod::value); - - struct FileSystemProxyErrorInfo { - u32 rom_fs_remount_for_data_corruption_count; - u32 rom_fs_unrecoverable_data_corruption_by_remount_count; - fat::FatError fat_fs_error; - u32 rom_fs_recovered_by_invalidate_cache_count; - u32 save_data_index_count; - fat::FatReportInfo1 bis_system_fat_report_info_1; - fat::FatReportInfo1 bis_user_fat_report_info_1; - fat::FatReportInfo1 sd_card_fat_report_info_1; - fat::FatReportInfo2 bis_system_fat_report_info_2; - fat::FatReportInfo2 bis_user_fat_report_info_2; - fat::FatReportInfo2 sd_card_fat_report_info_2; - u32 rom_fs_deep_retry_start_count; - u32 rom_fs_unrecoverable_by_game_card_access_failed_count; - fat::FatSafeInfo bis_system_fat_safe_info; - fat::FatSafeInfo bis_user_fat_safe_info; - - u8 reserved[0x18]; - }; - static_assert(sizeof(FileSystemProxyErrorInfo) == 0x80); - static_assert(util::is_pod::value); - - Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); - Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); - - Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out); - -} diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp index ccfc0fc8f..2ebb52fa6 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp @@ -19,9 +19,6 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: Unknown */ - constexpr inline size_t GameCardCidSize = 0x10; - constexpr inline size_t GameCardDeviceIdSize = 0x10; - enum class GameCardPartition { Update = 0, Normal = 1, @@ -50,44 +47,9 @@ namespace ams::fs { Terra = 1, }; - struct GameCardErrorReportInfo { - u16 game_card_crc_error_num; - u16 reserved1; - u16 asic_crc_error_num; - u16 reserved2; - u16 refresh_num; - u16 reserved3; - u16 retry_limit_out_num; - u16 timeout_retry_num; - u16 asic_reinitialize_failure_detail; - u16 insertion_count; - u16 removal_count; - u16 asic_reinitialize_num; - u32 initialize_count; - u16 asic_reinitialize_failure_num; - u16 awaken_failure_num; - u16 reserved4; - u16 refresh_succeeded_count; - u32 last_read_error_page_address; - u32 last_read_error_page_count; - u32 awaken_count; - u32 read_count_from_insert; - u32 read_count_from_awaken; - u8 reserved5[8]; - }; - static_assert(util::is_pod::value); - static_assert(sizeof(GameCardErrorReportInfo) == 0x40); - using GameCardHandle = u32; Result GetGameCardHandle(GameCardHandle *out); Result MountGameCardPartition(const char *name, GameCardHandle handle, GameCardPartition partition); - Result GetGameCardCid(void *dst, size_t size); - Result GetGameCardDeviceId(void *dst, size_t size); - - Result GetGameCardErrorReportInfo(GameCardErrorReportInfo *out); - - bool IsGameCardInserted(); - } diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp deleted file mode 100644 index 3f72e819e..000000000 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp +++ /dev/null @@ -1,42 +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 . - */ -#pragma once -#include - -namespace ams::fs { - - struct MemoryReportInfo { - u64 pooled_buffer_peak_free_size; - u64 pooled_buffer_retried_count; - u64 pooled_buffer_reduce_allocation_count; - u64 buffer_manager_peak_free_size; - u64 buffer_manager_retried_count; - u64 exp_heap_peak_free_size; - u64 buffer_pool_peak_free_size; - u64 patrol_read_allocate_buffer_success_count; - u64 patrol_read_allocate_buffer_failure_count; - u64 buffer_manager_peak_total_allocatable_size; - u64 buffer_pool_max_allocate_size; - u64 pooled_buffer_failed_ideal_allocation_count_on_async_access; - - u8 reserved[0x20]; - }; - static_assert(sizeof(MemoryReportInfo) == 0x80); - static_assert(util::is_pod::value); - - Result GetAndClearMemoryReportInfo(MemoryReportInfo *out); - -} diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp deleted file mode 100644 index b954378be..000000000 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp +++ /dev/null @@ -1,57 +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 . - */ -#pragma once -#include - -namespace ams::fs { - - constexpr inline size_t MmcCidSize = 0x10; - - constexpr inline size_t MmcExtendedCsdSize = 0x200; - - constexpr inline int MmcExtendedCsdOffsetReEolInfo = 267; - constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypA = 268; - constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypB = 269; - - enum MmcSpeedMode { - MmcSpeedMode_Identification = 0, - MmcSpeedMode_LegacySpeed = 1, - MmcSpeedMode_HighSpeed = 2, - MmcSpeedMode_Hs200 = 3, - MmcSpeedMode_Hs400 = 4, - MmcSpeedMode_Unknown = 5, - }; - - enum class MmcPartition { - UserData = 0, - BootPartition1 = 1, - BootPartition2 = 2, - }; - - Result GetMmcCid(void *dst, size_t size); - - inline void ClearMmcCidSerialNumber(u8 *cid) { - /* Clear the serial number from the cid. */ - std::memset(cid + 1, 0, 4); - } - - Result GetMmcSpeedMode(MmcSpeedMode *out); - - Result GetMmcPatrolCount(u32 *out); - - Result GetMmcExtendedCsd(void *dst, size_t size); - -} diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp deleted file mode 100644 index e2f000002..000000000 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp +++ /dev/null @@ -1,26 +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 . - */ -#pragma once -#include -#include -#include - -namespace ams::fs { - - /* ACCURATE_TO_VERSION: 17.5.0.0 */ - Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr); - -} \ No newline at end of file diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp index b72d90709..6ceda83db 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp @@ -21,38 +21,12 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: Unknown */ class IEventNotifier; - constexpr inline size_t SdCardCidSize = 0x10; - - enum SdCardSpeedMode { - SdCardSpeedMode_Identification = 0, - SdCardSpeedMode_DefaultSpeed = 1, - SdCardSpeedMode_HighSpeed = 2, - SdCardSpeedMode_Sdr12 = 3, - SdCardSpeedMode_Sdr25 = 4, - SdCardSpeedMode_Sdr50 = 5, - SdCardSpeedMode_Sdr104 = 6, - SdCardSpeedMode_Ddr50 = 7, - SdCardSpeedMode_Unknown = 8, - }; - struct EncryptionSeed { char value[0x10]; }; static_assert(util::is_pod::value); static_assert(sizeof(EncryptionSeed) == 0x10); - Result GetSdCardCid(void *dst, size_t size); - - inline void ClearSdCardCidSerialNumber(u8 *cid) { - /* Clear the serial number from the cid. */ - std::memset(cid + 2, 0, 4); - } - - Result GetSdCardUserAreaSize(s64 *out); - Result GetSdCardProtectedAreaSize(s64 *out); - - Result GetSdCardSpeedMode(SdCardSpeedMode *out); - Result MountSdCard(const char *name); Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name); 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 7a2778a9e..c05920cc8 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 @@ -104,7 +104,6 @@ namespace ams::fssrv { Result GetRightsId(ams::sf::Out out, ncm::ProgramId program_id, ncm::StorageId storage_id); Result RegisterExternalKey(const fs::RightsId &rights_id, const spl::AccessKey &access_key); Result UnregisterAllExternalKey(); - Result GetProgramId(ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr); Result GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path); Result GetRightsIdAndKeyGenerationByPathObsolete(ams::sf::Out out, ams::sf::Out out_key_generation, const fssrv::sf::FspPath &path); Result GetRightsIdAndKeyGenerationByPath(ams::sf::Out out, ams::sf::Out out_key_generation, const fssrv::sf::FspPath &path, fs::ContentAttributes attr); @@ -121,7 +120,6 @@ namespace ams::fssrv { Result IsSignedSystemPartitionOnSdCardValid(ams::sf::Out out); Result OpenAccessFailureDetectionEventNotifier(); /* ... */ - Result GetAndClearErrorInfo(ams::sf::Out out); Result RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count); Result SetBisRootForHost(u32 id, const fssrv::sf::FspPath &path); Result SetSaveDataSize(s64 size, s64 journal_size); @@ -132,7 +130,6 @@ namespace ams::fssrv { Result OutputAccessLogToSdCard(const ams::sf::InBuffer &buf); Result RegisterUpdatePartition(); Result OpenRegisteredUpdatePartition(ams::sf::Out> out); - Result GetAndClearMemoryReportInfo(ams::sf::Out out); /* ... */ Result GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count); Result GetFsStackUsage(ams::sf::Out out, u32 type); @@ -149,9 +146,7 @@ namespace ams::fssrv { /* fsp-ldr */ 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 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 OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); Result IsArchivedProgram(ams::sf::Out out, u64 process_id); }; static_assert(sf::IsIFileSystemProxy); @@ -170,21 +165,11 @@ namespace ams::fssrv { R_THROW(fs::ResultPortAcceptableCountLimited()); } - 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, ams::sf::Out 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 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_device_operator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp index c251223c5..7334ff861 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp @@ -16,27 +16,12 @@ #pragma once #include #include -#include -#include /* TODO */ /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetSdCardSpeedMode, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, GetSdCardCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, GetSdCardUserAreaSize, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetSdCardProtectedAreaSize, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetAndClearSdCardErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ - AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 113, Result, GetAndClearMmcErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ - AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 208, Result, GetGameCardIdSet, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 217, Result, GetGameCardErrorReportInfo, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 218, Result, GetGameCardDeviceId, (ams::sf::OutBuffer out, s64 size), (out, size)) + AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IDeviceOperator, AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO, 0x1484E21C) diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp index 5ccee0cdf..5e8fade2f 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_FILE_SYSTEM_PROXY_INTERFACE_INFO(C, H) \ @@ -117,7 +115,6 @@ AMS_SF_METHOD_INFO(C, H, 615, Result, QuerySaveDataInternalStorageTotalSize, (), (), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 616, Result, GetSaveDataCommitId, (), (), hos::Version_6_0_0) \ AMS_SF_METHOD_INFO(C, H, 617, Result, UnregisterExternalKey, (const fs::RightsId &rights_id), (rights_id), hos::Version_7_0_0) \ - AMS_SF_METHOD_INFO(C, H, 618, Result, GetProgramId, (ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr), (out, path, attr), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 620, Result, SetSdCardEncryptionSeed, (const fs::EncryptionSeed &seed), (seed), hos::Version_2_0_0) \ AMS_SF_METHOD_INFO(C, H, 630, Result, SetSdCardAccessibility, (bool accessible), (accessible), hos::Version_4_0_0) \ AMS_SF_METHOD_INFO(C, H, 631, Result, IsSdCardAccessible, (ams::sf::Out out), (out), hos::Version_4_0_0) \ @@ -127,7 +124,7 @@ /* AMS_SF_METHOD_INFO(C, H, 702, Result, IsAccessFailureDetected, (), (), hos::Version_5_0_0) */ \ /* AMS_SF_METHOD_INFO(C, H, 710, Result, ResolveAccessFailure, (), (), hos::Version_5_0_0) */ \ /* AMS_SF_METHOD_INFO(C, H, 720, Result, AbandonAccessFailure, (), (), hos::Version_5_0_0) */ \ - AMS_SF_METHOD_INFO(C, H, 800, Result, GetAndClearErrorInfo, (ams::sf::Out out), (out), hos::Version_2_0_0) \ + /* AMS_SF_METHOD_INFO(C, H, 800, Result, GetAndClearErrorInfo, (), (), hos::Version_2_0_0) */ \ AMS_SF_METHOD_INFO(C, H, 810, Result, RegisterProgramIndexMapInfo, (const ams::sf::InBuffer &buffer, s32 count), (buffer, count), hos::Version_7_0_0) \ AMS_SF_METHOD_INFO(C, H, 1000, Result, SetBisRootForHost, (u32 id, const fssrv::sf::FspPath &path), (id, path), hos::Version_Min, hos::Version_9_2_0) \ AMS_SF_METHOD_INFO(C, H, 1001, Result, SetSaveDataSize, (s64 size, s64 journal_size), (size, journal_size)) \ @@ -138,7 +135,7 @@ AMS_SF_METHOD_INFO(C, H, 1006, Result, OutputAccessLogToSdCard, (const ams::sf::InBuffer &buf), (buf)) \ AMS_SF_METHOD_INFO(C, H, 1007, Result, RegisterUpdatePartition, (), (), hos::Version_4_0_0) \ AMS_SF_METHOD_INFO(C, H, 1008, Result, OpenRegisteredUpdatePartition, (ams::sf::Out> out), (out), hos::Version_4_0_0) \ - AMS_SF_METHOD_INFO(C, H, 1009, Result, GetAndClearMemoryReportInfo, (ams::sf::Out out), (out), hos::Version_4_0_0) \ + /* AMS_SF_METHOD_INFO(C, H, 1009, Result, GetAndClearMemoryReportInfo, (ams::sf::Out out), (out), hos::Version_4_0_0) */ \ /* AMS_SF_METHOD_INFO(C, H, 1010, Result, SetDataStorageRedirectTarget, (), (), hos::Version_5_1_0, hos::Version_6_2_0) */ \ AMS_SF_METHOD_INFO(C, H, 1011, Result, GetProgramIndexForAccessLog, (ams::sf::Out out_idx, ams::sf::Out out_count), (out_idx, out_count), hos::Version_7_0_0) \ AMS_SF_METHOD_INFO(C, H, 1012, Result, GetFsStackUsage, (ams::sf::Out out, u32 type), (out, type), hos::Version_9_0_0) \ 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 0e55e2562..4ba1f0a8f 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 @@ -20,14 +20,12 @@ #include #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, 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) +/* ACCURATE_TO_VERSION: 13.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, OpenCodeFileSystem, (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) \ + 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 17dfb656b..4ca3316e2 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp @@ -16,7 +16,6 @@ #pragma once #include #include -#include namespace ams::fssystem { @@ -26,13 +25,10 @@ namespace ams::fssystem { void InvalidateHardwareAesKey(); - bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation); - - 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 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation); const u8 *GetAcidSignatureKeyPublicExponent(); + constexpr inline size_t AcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize; constexpr inline size_t AcidSignatureKeyPublicExponentSize = NcaCryptoConfiguration::Rsa2048KeyPublicExponentSize; } diff --git a/libraries/libstratosphere/include/stratosphere/gc.hpp b/libraries/libstratosphere/include/stratosphere/gc.hpp index 80007a74d..8eb6b8ec8 100644 --- a/libraries/libstratosphere/include/stratosphere/gc.hpp +++ b/libraries/libstratosphere/include/stratosphere/gc.hpp @@ -18,4 +18,3 @@ #include #include #include -#include diff --git a/libraries/libstratosphere/include/stratosphere/gc/gc.hpp b/libraries/libstratosphere/include/stratosphere/gc/gc.hpp deleted file mode 100644 index 797bb8bb4..000000000 --- a/libraries/libstratosphere/include/stratosphere/gc/gc.hpp +++ /dev/null @@ -1,30 +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 . - */ -#pragma once -#include -#include - -namespace ams::gc { - - struct GameCardIdSet { - gc::impl::CardId1 id1; - gc::impl::CardId2 id2; - gc::impl::CardId3 id3; - }; - static_assert(util::is_pod::value); - static_assert(sizeof(GameCardIdSet) == 0xC); - -} diff --git a/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp b/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp index a6b1043f8..98b56c8b2 100644 --- a/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp @@ -76,11 +76,6 @@ namespace ams::gc::impl { static_assert(util::is_pod::value); static_assert(sizeof(CardHeaderEncryptedData) == 0x70); - enum MakerCodeForCardId1 : u8 { - MakerCodeForCardId1_MegaChips = 0xC2, - MakerCodeForCardId1_Lapis = 0xAE, - }; - enum MemoryCapacity : u8 { MemoryCapacity_1GB = 0xFA, MemoryCapacity_2GB = 0xF8, @@ -90,33 +85,6 @@ namespace ams::gc::impl { MemoryCapacity_32GB = 0xE2, }; - enum MemoryType : u8 { - MemoryType_T1RomFast = 0x01, - MemoryType_T2RomFast = 0x02, - MemoryType_T1NandFast = 0x09, - MemoryType_T2NandFast = 0x0A, - MemoryType_T1RomLate = 0x21, - MemoryType_T2RomLate = 0x22, - MemoryType_T1NandLate = 0x29, - MemoryType_T2NandLate = 0x2A, - }; - - enum CardSecurityNumber : u8 { - CardSecurityNumber_0 = 0x00, - CardSecurityNumber_1 = 0x01, - CardSecurityNumber_2 = 0x02, - CardSecurityNumber_3 = 0x03, - CardSecurityNumber_4 = 0x04, - }; - - enum CardType : u8 { - CardType_Rom = 0x00, - CardType_Writable_Dev_T1 = 0x01, - CardType_Writable_Prod_T1 = 0x02, - CardType_Writable_Dev_T2 = 0x03, - CardType_Writable_Prod_T2 = 0x04, - }; - enum AccessControl1ClockRate : u32 { AccessControl1ClockRate_25MHz = 0x00A10011, AccessControl1ClockRate_50MHz = 0x00A10010, @@ -127,23 +95,6 @@ namespace ams::gc::impl { SelSec_T2 = 2, }; - struct CardId1 { - MakerCodeForCardId1 maker_code; - MemoryCapacity memory_capacity; - u8 reserved; - MemoryType memory_type; - }; - - struct CardId2 { - CardSecurityNumber card_security_number; - CardType card_type; - u8 reserved[2]; - }; - - struct CardId3 { - u8 reserved[4]; - }; - struct CardHeader { static constexpr u32 Magic = util::FourCC<'H','E','A','D'>::Code; diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 3a0ac040a..4b7dc1ed0 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -80,20 +80,6 @@ namespace ams::hos { Version_16_0_2 = ::ams::TargetFirmware_16_0_2, Version_16_0_3 = ::ams::TargetFirmware_16_0_3, Version_16_1_0 = ::ams::TargetFirmware_16_1_0, - 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_20_1_0 = ::ams::TargetFirmware_20_1_0, - Version_20_1_1 = ::ams::TargetFirmware_20_1_1, - Version_20_1_5 = ::ams::TargetFirmware_20_1_5, - Version_20_2_0 = ::ams::TargetFirmware_20_2_0, - Version_20_3_0 = ::ams::TargetFirmware_20_3_0, 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 39c0bc3da..651b25bff 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, 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)) +#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)) 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 310c6fa51..dd5d34b9a 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, ldr::ProgramAttributes attrs); - Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit); + Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result UnpinProgram(PinId pin_id); Result SetEnabledProgramVerification(bool enabled); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); /* Atmosphere extension API. */ - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); 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 5cc2fbb8b..328957aae 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -19,8 +19,6 @@ #include #include #include -#include -#include namespace ams::ldr { @@ -35,10 +33,9 @@ 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) == 0x410, "ProgramInfo definition!"); + static_assert(util::is_pod::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!"); enum ProgramInfoFlag { ProgramInfoFlag_SystemModule = (0 << 0), @@ -227,8 +224,6 @@ namespace ams::ldr { MetaFlag_OptimizeMemoryAllocation = (1 << 4), MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5), - MetaFlag_EnableAliasRegionExtraSize = (1 << 6), - MetaFlag_PreventCodeReads = (1 << 7), }; enum AddressSpaceType { @@ -266,10 +261,4 @@ 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_manager_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp index 348acc486..2c4cb06f2 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp @@ -239,12 +239,8 @@ namespace ams::ncm { Result InitializeIntegratedContentMetaDatabaseRoot(IntegratedContentMetaDatabaseRoot *out, const IntegratedContentStorageConfig *config, size_t root_idx, size_t root_count); Result BuildContentMetaDatabase(StorageId storage_id); - Result BuildContentMetaDatabaseImpl(StorageId storage_id); Result ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition); Result ImportContentMetaDatabaseImpl(ContentMetaDatabaseRoot *root, const char *import_mount_name); - private: - /* Helpers for unofficial functionality. */ - bool IsNeedRebuildSystemContentMetaDatabase(); public: /* Actual commands. */ Result CreateContentStorage(StorageId storage_id); diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp index 4b7ac2ba8..b00fe8cb1 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp @@ -16,7 +16,6 @@ #pragma once #include #include -#include #include #include #include @@ -59,7 +58,7 @@ namespace ams::ncm { u16 content_count; u16 content_meta_count; u8 attributes; - ContentMetaPlatform platform; + StorageId storage_id; }; static_assert(sizeof(ContentMetaHeader) == 0x8); @@ -68,7 +67,7 @@ namespace ams::ncm { u64 id; u32 version; ContentMetaType type; - ContentMetaPlatform platform; + u8 reserved_0D; u16 extended_header_size; u16 content_count; u16 content_meta_count; @@ -80,6 +79,7 @@ namespace ams::ncm { u8 reserved_1C[4]; }; static_assert(sizeof(PackagedContentMetaHeader) == 0x20); + static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_0D) == 0x0D); static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_1C) == 0x1C); using InstallContentMetaHeader = PackagedContentMetaHeader; 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 6c6a8adec..947fbfaad 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp @@ -221,16 +221,6 @@ namespace ams::ncm { AMS_ASSERT(m_interface != nullptr); R_RETURN(m_interface->GetContentInfoByTypeAndIdOffset(out_content_info, key, type, id_offset)); } - - Result GetPlatform(ContentMetaPlatform *out, const ContentMetaKey &key) { - 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 f8888e49f..dc693875a 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->GetFragmentSetAddress(delta_index, fragment_set_index)); + return reinterpret_cast(this->GetFragmentSetIndex(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_content_meta_platform.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp deleted file mode 100644 index 2a08d8419..000000000 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp +++ /dev/null @@ -1,25 +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 . - */ -#pragma once -#include - -namespace ams::ncm { - - enum class ContentMetaPlatform : u8 { - Nx = 0x0, - }; - -} diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp index 64512681b..a7ad71aca 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp @@ -207,11 +207,6 @@ namespace ams::ncm { R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdWithCacheDeprecated(out_rights_id, cache_content_id, placeholder_id)); } } - - Result GetProgramId(ncm::ProgramId *out, ContentId content_id, fs::ContentAttributes attr) { - AMS_ASSERT(m_interface != nullptr); - R_RETURN(m_interface->GetProgramId(out, content_id, attr)); - } }; } 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 39c04cd03..411701b79 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 @@ -43,9 +43,7 @@ AMS_SF_METHOD_INFO(C, H, 22, Result, GetOwnerApplicationId, (sf::Out out_id, const ncm::ContentMetaKey &key), (out_id, key), hos::Version_10_0_0) \ 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, 27, Result, HasAttributes, (sf::Out out, u8 attr_mask), (out, attr_mask), hos::Version_20_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_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp index 3ea0b73fb..250e84dc9 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp @@ -58,7 +58,6 @@ AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCacheDeprecated, (sf::Out out_rights_id, ncm::ContentId cache_content_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, cache_content_id, placeholder_id), hos::Version_8_0_0, hos::Version_15_0_1) \ AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCache, (sf::Out out_rights_id, ncm::PlaceHolderId placeholder_id, ncm::ContentId cache_content_id, fs::ContentAttributes attr), (out_rights_id, placeholder_id, cache_content_id, attr), hos::Version_16_0_0) \ AMS_SF_METHOD_INFO(C, H, 28, Result, RegisterPath, (const ncm::ContentId &content_id, const ncm::Path &path), (content_id, path), hos::Version_13_0_0) \ - AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) \ - AMS_SF_METHOD_INFO(C, H, 30, Result, GetProgramId, (sf::Out out, ncm::ContentId content_id, fs::ContentAttributes attr), (out, content_id, attr), hos::Version_17_0_0) + AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentStorage, AMS_NCM_I_CONTENT_STORAGE_INTERFACE_INFO, 0xFEAE3DD1) 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 8d0e79ff0..05ebe160d 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 @@ -71,8 +71,6 @@ namespace ams::ncm { Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key); 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_integrated_content_storage_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp index 40a3063d0..f29c3e0f4 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp @@ -79,7 +79,6 @@ namespace ams::ncm { Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr); Result RegisterPath(const ContentId &content_id, const Path &path); Result ClearRegisteredPath(); - Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr); /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } 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 b8e7bcd41..b02c38fc5 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,15 +121,13 @@ 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 || program_id == AtmosphereProgramId::AtmosphereMemlet; + return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager; } 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 66faf57e2..a34f2272d 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,10 +19,8 @@ #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, (), ()) \ - 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)) +#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_DEFINE_INTERFACE(ams::pm::impl, IBootModeInterface, AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO, 0x96D01649) diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp index 7c9676f86..f9e063baa 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp @@ -27,7 +27,7 @@ AMS_SF_METHOD_INFO(C, H, 4, Result, GetApplicationProcessId, (sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 5, Result, HookToCreateApplicationProcess, (sf::OutCopyHandle out_hook), (out_hook)) \ AMS_SF_METHOD_INFO(C, H, 6, Result, ClearHook, (u32 which), (which), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessInfo, (sf::OutCopyHandle out_process_handle, sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_process_handle, out_loc, out_status, process_id)) \ AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetCurrentLimitInfo, (sf::Out out_cur_val, sf::Out out_lim_val, u32 group, u32 resource), (out_cur_val, out_lim_val, group, resource)) diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp index 6eeda3216..35f5d7089 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp @@ -21,8 +21,8 @@ #define AMS_PM_I_INFORMATION_INTERFACE_INTERFACE_INFO(C, H) \ AMS_SF_METHOD_INFO(C, H, 0, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetAppletResourceLimitCurrentValue, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, GetAppletResourceLimitPeakValue, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetAppletCurrentResourceLimitValues, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetAppletPeakResourceLimitValues, (sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessId, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmosphereGetProcessInfo, (sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_loc, out_status, process_id)) diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp index 4a5d53fa0..7a896ae66 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp @@ -28,7 +28,6 @@ namespace ams::pm::dmnt { Result GetProcessId(os::ProcessId *out_process_id, const ncm::ProgramId program_id); Result GetApplicationProcessId(os::ProcessId *out_process_id); Result HookToCreateApplicationProcess(os::NativeHandle *out_handle); - Result HookToCreateProcess(os::NativeHandle *out_handle, const ncm::ProgramId program_id); Result AtmosphereGetProcessInfo(os::NativeHandle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); #if defined(ATMOSPHERE_OS_HORIZON) diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp index 484c4fa7e..c771eb33f 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp @@ -29,8 +29,8 @@ namespace ams::pm::info { Result GetProcessId(os::ProcessId *out_process_id, ncm::ProgramId program_id); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); - Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out); - Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out); + Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out); + Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out); Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp index 0fb6e3c87..9266302fc 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp @@ -52,7 +52,7 @@ namespace ams::pm { LaunchFlagsDeprecated_SignalOnStart = (1 << 5), }; - struct ResourceLimitValue { + struct ResourceLimitValues { u64 physical_memory; u32 thread_count; u32 event_count; diff --git a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp index 4a1ce2684..886b771da 100644 --- a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp @@ -135,15 +135,14 @@ 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_version; + u8 m_reserved_14[0x4]; u32 m_size; - u32 m_flags; + u8 m_reserved_1C[0x4]; u32 m_text_offset; u32 m_text_size; u32 m_ro_offset; @@ -159,22 +158,10 @@ 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/settings/settings_types.hpp b/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp index 4290a0eba..410bad5eb 100644 --- a/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp @@ -53,8 +53,7 @@ namespace ams::settings { /* 4.0.0+ */ Language_SimplifiedChinese, Language_TraditionalChinese, - /* 10.1.0+ */ - Language_PortugueseBr, + Language_Count, }; @@ -93,8 +92,6 @@ namespace ams::settings { /* 4.0.0+ */ AMS_MATCH_LANGUAGE(SimplifiedChinese, "zh-Hans") AMS_MATCH_LANGUAGE(TraditionalChinese, "zh-Hant") - /* 10.1.0+ */ - AMS_MATCH_LANGUAGE(PortugueseBr, "pt-BR") #undef AMS_MATCH_LANGUAGE else { static_assert(Lang != Language_Japanese); } } @@ -119,8 +116,6 @@ namespace ams::settings { /* 4.0.0+ */ EncodeLanguage(), EncodeLanguage(), - /* 10.1.0+ */ - EncodeLanguage(), }; return EncodedLanguages[language]; } @@ -161,11 +156,7 @@ namespace ams::settings { } constexpr inline bool IsValidLanguageCodeDeprecated(const LanguageCode &lc) { - return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); - } - - constexpr inline bool IsValidLanguageCodeDeprecated2(const LanguageCode &lc) { - return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); + return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); } constexpr inline bool IsValidLanguageCode(const LanguageCode &lc) { diff --git a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp index e73a6642c..d13934320 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp @@ -62,7 +62,7 @@ namespace ams::sf::cmif { } constexpr size_t GetImplOutDataTotalSize() const { - return m_impl_metadata.GetUnalignedOutDataSize() + m_impl_metadata.GetOutHeadersSize(); + return m_impl_metadata.GetOutDataSize() + m_impl_metadata.GetOutHeadersSize(); } public: /* Used to enabled templated message processors. */ @@ -80,12 +80,12 @@ namespace ams::sf::cmif { const auto runtime_metadata = m_impl_processor->GetRuntimeMetadata(); return ServerMessageRuntimeMetadata { - .in_data_size = static_cast(runtime_metadata.GetInDataSize() + runtime_metadata.GetInObjectCount() * sizeof(DomainObjectId)), - .unaligned_out_data_size = static_cast(runtime_metadata.GetOutDataSize() + runtime_metadata.GetOutObjectCount() * sizeof(DomainObjectId)), - .in_headers_size = static_cast(runtime_metadata.GetInHeadersSize() + sizeof(CmifDomainInHeader)), - .out_headers_size = static_cast(runtime_metadata.GetOutHeadersSize() + sizeof(CmifDomainOutHeader)), - .in_object_count = 0, - .out_object_count = 0, + .in_data_size = static_cast(runtime_metadata.GetInDataSize() + runtime_metadata.GetInObjectCount() * sizeof(DomainObjectId)), + .out_data_size = static_cast(runtime_metadata.GetOutDataSize() + runtime_metadata.GetOutObjectCount() * sizeof(DomainObjectId)), + .in_headers_size = static_cast(runtime_metadata.GetInHeadersSize() + sizeof(CmifDomainInHeader)), + .out_headers_size = static_cast(runtime_metadata.GetOutHeadersSize() + sizeof(CmifDomainOutHeader)), + .in_object_count = 0, + .out_object_count = 0, }; } diff --git a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp index ef454e091..ca90235e6 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp @@ -28,7 +28,7 @@ namespace ams::sf::cmif { /* This is needed for non-templated domain message processing. */ struct ServerMessageRuntimeMetadata { u16 in_data_size; - u16 unaligned_out_data_size; + u16 out_data_size; u8 in_headers_size; u8 out_headers_size; u8 in_object_count; @@ -39,11 +39,7 @@ namespace ams::sf::cmif { } constexpr size_t GetOutDataSize() const { - return static_cast(util::AlignUp(this->unaligned_out_data_size, sizeof(u32))); - } - - constexpr size_t GetUnalignedOutDataSize() const { - return static_cast(this->unaligned_out_data_size); + return static_cast(this->out_data_size); } constexpr size_t GetInHeadersSize() const { diff --git a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index c91d4480f..83024df40 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -472,7 +472,6 @@ namespace ams::sf::impl { static constexpr size_t InDataSize = util::AlignUp(InDataOffsets[NumInDatas], alignof(u16)); static constexpr std::array OutDataOffsets = RawDataOffsetCalculator::Offsets; - static constexpr size_t UnalignedOutDataSize = OutDataOffsets[NumOutDatas]; static constexpr size_t OutDataSize = util::AlignUp(OutDataOffsets[NumOutDatas], alignof(u32)); static constexpr size_t OutDataAlign = [] { if constexpr (std::tuple_size::value) { @@ -493,12 +492,12 @@ namespace ams::sf::impl { /* Used by server message processor at runtime. */ static constexpr inline const cmif::ServerMessageRuntimeMetadata RuntimeMetadata = cmif::ServerMessageRuntimeMetadata{ - .in_data_size = InDataSize, - .unaligned_out_data_size = UnalignedOutDataSize, - .in_headers_size = sizeof(CmifInHeader), - .out_headers_size = sizeof(CmifOutHeader), - .in_object_count = NumInObjects, - .out_object_count = NumOutObjects, + .in_data_size = InDataSize, + .out_data_size = OutDataSize, + .in_headers_size = sizeof(CmifInHeader), + .out_headers_size = sizeof(CmifOutHeader), + .in_object_count = NumInObjects, + .out_object_count = NumOutObjects, }; /* Construction of argument serialization structs. */ diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp index bc134fd91..32286f48f 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp @@ -42,7 +42,7 @@ namespace ams::sf { } else if constexpr(TransferMode == BufferTransferMode::AutoSelect) { return SfBufferAttr_HipcAutoSelect; } else { - static_assert(false, "Invalid BufferTransferMode"); + static_assert(TransferMode != TransferMode, "Invalid BufferTransferMode"); } }(); diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp index 56ca7f5a7..64a491eb0 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp @@ -29,7 +29,7 @@ namespace ams::sf { private: struct Holder { MemoryResource *allocator; - alignas(alignof(T)) std::byte storage[sizeof(T)]; + typename std::aligned_storage::type storage; }; public: void *Allocate(size_t size) { diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp index 6ec6fcdca..5a30b09ee 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp @@ -57,7 +57,7 @@ namespace ams::sf { struct Globals { ExpHeapAllocator allocator; - alignas(0x10) std::byte buffer[Size == 0 ? 1 : Size]; + typename std::aligned_storage::type buffer; }; static constinit inline Globals _globals = {}; diff --git a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp index 1a79d67b1..db2354329 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp @@ -70,7 +70,6 @@ namespace ams::spl::impl { Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size); Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result LoadPreparedAesKey(s32 keyslot, const AccessKey &access_key); - Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); /* FS */ Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option); diff --git a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp index 237c3124e..0fda18172 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp @@ -28,7 +28,6 @@ AMS_SF_METHOD_INFO(C, H, 28, Result, DecryptAndStoreDrmDeviceCertKey, (const sf::InPointerBuffer &src, spl::AccessKey access_key, spl::KeySource key_source), (src, access_key, key_source), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 29, Result, ModularExponentiateWithDrmDeviceCertKey, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod), (out, base, mod), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 31, Result, PrepareEsArchiveKey, (sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), (out_access_key, base, mod, label_digest, generation), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 32, Result, LoadPreparedAesKey, (s32 keyslot, spl::AccessKey access_key), (keyslot, access_key), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 33, Result, PrepareEsUnknown2Key, (sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), (out_access_key, base, mod, label_digest, generation), hos::Version_18_0_0) + AMS_SF_METHOD_INFO(C, H, 32, Result, LoadPreparedAesKey, (s32 keyslot, spl::AccessKey access_key), (keyslot, access_key), hos::Version_6_0_0) AMS_SF_DEFINE_INTERFACE_WITH_BASE(ams::spl::impl, IEsInterface, ::ams::spl::impl::IDeviceUniqueDataInterface, AMS_SPL_I_ES_INTERFACE_INTERFACE_INFO, 0x346D5001) diff --git a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp index 11c80ad48..08444261d 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -98,7 +98,6 @@ namespace ams::spl { enum class EsDeviceUniqueKeyType { TitleKey = 0, ArchiveKey = 1, - Unknown2 = 2, }; struct AsyncOperationKey { diff --git a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index d68a56f33..8e34756de 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, int64_t value, int64_t timeout_ns) { + ALWAYS_INLINE Result WaitForAddress(::ams::svc::Address address, ::ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { R_RETURN(::svcWaitForAddress(reinterpret_cast(static_cast(address)), arb_type, value, timeout_ns)); } @@ -331,8 +331,8 @@ R_RETURN(::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address)); } - ALWAYS_INLINE Result QueryMemoryMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { - R_RETURN(::svcQueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + R_RETURN(::svcQueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } ALWAYS_INLINE Result LegacyQueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { @@ -503,12 +503,12 @@ ::svcCallSecureMonitor(reinterpret_cast<::SecmonArgs *>(args)); } - ALWAYS_INLINE Result MapInsecurePhysicalMemory(::ams::svc::Address address, ::ams::svc::Size size) { - R_RETURN(::svcMapInsecurePhysicalMemory(reinterpret_cast(static_cast(address)), size)); + ALWAYS_INLINE Result MapInsecureMemory(::ams::svc::Address address, ::ams::svc::Size size) { + R_RETURN(::svcMapInsecureMemory(reinterpret_cast(static_cast(address)), size)); } - ALWAYS_INLINE Result UnmapInsecurePhysicalMemory(::ams::svc::Address address, ::ams::svc::Size size) { - R_RETURN(::svcUnmapInsecurePhysicalMemory(reinterpret_cast(static_cast(address)), size)); + ALWAYS_INLINE Result UnmapInsecureMemory(::ams::svc::Address address, ::ams::svc::Size size) { + R_RETURN(::svcUnmapInsecureMemory(reinterpret_cast(static_cast(address)), size)); } } diff --git a/libraries/libstratosphere/libstratosphere.mk b/libraries/libstratosphere/libstratosphere.mk index faec4fdb3..b10f27f13 100644 --- a/libraries/libstratosphere/libstratosphere.mk +++ b/libraries/libstratosphere/libstratosphere.mk @@ -154,14 +154,12 @@ 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) -# 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 +# 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 endif #--------------------------------------------------------------------------------- diff --git a/libraries/libstratosphere/source/ams/ams_emummc_api.cpp b/libraries/libstratosphere/source/ams/ams_emummc_api.cpp index ca47cc455..ce3b7f9f0 100644 --- a/libraries/libstratosphere/source/ams/ams_emummc_api.cpp +++ b/libraries/libstratosphere/source/ams/ams_emummc_api.cpp @@ -73,7 +73,7 @@ namespace ams::emummc { /* Retrieve and cache values. */ { - alignas(os::MemoryPageSize) std::byte path_storage[2 * (MaxDirLen + 1)]; + typename std::aligned_storage<2 * (MaxDirLen + 1), os::MemoryPageSize>::type path_storage; struct { char file_path[MaxDirLen + 1]; diff --git a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp index d48b0ce57..6c2a7cccb 100644 --- a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp +++ b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp @@ -39,10 +39,6 @@ namespace ams::exosphere { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 3)); } - void ForceRebootByPmic() { - R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 4)); - } - void ForceShutdown() { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1)); } 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 5f7f296a6..e5f27fce6 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp @@ -450,9 +450,6 @@ 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/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp index eaa6befbe..8be38606a 100644 --- a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp +++ b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp @@ -16,16 +16,11 @@ #include #include "decodersrv_decoder_server_object.hpp" #include "../jpeg/decodersrv_software_jpeg_decoder.hpp" -#include "../jpeg/decodersrv_software_jpeg_shrinker.hpp" namespace ams::capsrv::server { namespace { - constexpr const int JpegShrinkQualities[] = { - 98, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0 - }; - Result DecodeJpegImpl(void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) { /* Clear the work memory. */ std::memset(work, 0, work_size); @@ -72,61 +67,6 @@ namespace ams::capsrv::server { R_SUCCEED(); } - Result ShrinkJpegImpl(u64 *out_size, void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) { - /* Validate parameters. */ - R_UNLESS(util::IsAligned(width, 0x10), capsrv::ResultAlbumOutOfRange()); - R_UNLESS(util::IsAligned(height, 0x4), capsrv::ResultAlbumOutOfRange()); - - R_UNLESS(dst != nullptr, capsrv::ResultInternalJpegOutBufferShortage()); - R_UNLESS(dst_size != 0, capsrv::ResultAlbumReadBufferShortage()); - - R_UNLESS(src_jpeg != nullptr, capsrv::ResultAlbumInvalidFileData()); - R_UNLESS(src_jpeg_size != 0, capsrv::ResultAlbumInvalidFileData()); - - /* Create the input. */ - const jpeg::SoftwareJpegShrinkerInput shrink_input = { - .jpeg = src_jpeg, - .jpeg_size = src_jpeg_size, - .width = width, - .height = height, - .fancy_upsampling = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableFancyUpsampling), - .block_smoothing = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableBlockSmoothing), - }; - - /* Create the output. */ - u64 shrunk_size = 0; - s32 shrunk_width = 0, shrunk_height = 0; - jpeg::SoftwareJpegShrinkerOutput shrink_output = { - .out_size = std::addressof(shrunk_size), - .out_width = std::addressof(shrunk_width), - .out_height = std::addressof(shrunk_height), - .dst = dst, - .dst_size = dst_size, - }; - - /* Try to shrink the jpeg at various quality levels. */ - for (auto quality : JpegShrinkQualities) { - /* Shrink at the current quality. */ - R_TRY_CATCH(jpeg::SoftwareJpegShrinker::ShrinkRgba8(shrink_output, shrink_input, quality, work, work_size)) { - /* If the output buffer isn't large enough to fit the output, we should try at a lower quality. */ - R_CATCH(capsrv::ResultInternalJpegOutBufferShortage) { - continue; - } - /* Nintendo doesn't catch this result, but our lack of work buffer use makes me think this may be necessary. */ - R_CATCH(capsrv::ResultInternalJpegWorkMemoryShortage) { - continue; - } - } R_END_TRY_CATCH; - - /* Write the output size. */ - *out_size = shrunk_size; - R_SUCCEED(); - } - - /* Nintendo aborts if no quality succeeds. */ - AMS_ABORT("ShrinkJpeg should succeed before this point\n"); - } - } Result DecoderControlService::DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option) { @@ -138,13 +78,4 @@ namespace ams::capsrv::server { R_RETURN(DecodeJpegImpl(out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size)); } - Result DecoderControlService::ShrinkJpeg(ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option) { - /* Get the work buffer. */ - void *work = g_work_memory.jpeg_decoder_memory; - size_t work_size = sizeof(g_work_memory.jpeg_decoder_memory); - - /* Call the shrink implementation. */ - R_RETURN(ShrinkJpegImpl(out_size.GetPointer(), out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size)); - } - } \ No newline at end of file diff --git a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp index 1c000ef11..feab40ba0 100644 --- a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp +++ b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp @@ -17,8 +17,7 @@ #include #define AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option)) \ - AMS_SF_METHOD_INFO(C, H, 4001, Result, ShrinkJpeg, (ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out_size, out, in, width, height, option)) + AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option)) AMS_SF_DEFINE_INTERFACE(ams::capsrv::sf, IDecoderControlService, AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO, 0xD168E90B) @@ -27,7 +26,6 @@ namespace ams::capsrv::server { class DecoderControlService final { public: Result DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option); - Result ShrinkJpeg(ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option); }; static_assert(capsrv::sf::IsIDecoderControlService); diff --git a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp deleted file mode 100644 index 119f52fe8..000000000 --- a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp +++ /dev/null @@ -1,236 +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 . - */ -#include -#include "decodersrv_software_jpeg_shrinker.hpp" -#include "capsrv_server_jpeg_library_types.hpp" -#include "capsrv_server_jpeg_error_handler.hpp" - - -namespace ams::capsrv::server::jpeg { - - #define CAPSRV_ABORT_UNLESS(expr) do { \ - const bool __capsrv_assert_res = (expr); \ - AMS_ASSERT(__capsrv_assert_res); \ - AMS_ABORT_UNLESS(__capsrv_assert_res); \ - } while (0) - - #define CAPSRV_ASSERT(expr) do { \ - const bool __capsrv_assert_res = (expr); \ - AMS_ASSERT(__capsrv_assert_res); \ - R_UNLESS(__capsrv_assert_res, capsrv::ResultAlbumError()); \ - } while (0) - - namespace { - - constexpr s32 ImageSizeHorizonalUnit = 0x10; - constexpr s32 ImageSizeVerticalUnitDecode = 0x4; - constexpr s32 ImageSizeVerticalUnitEncode = 0x8; - - constexpr s32 RgbColorComponentCount = 3; - constexpr s32 RgbaColorComponentCount = 4; - - Result GetRgbBufferSize(size_t *out_size, size_t *out_stride, s32 width, size_t work_size) { - /* Calculate the space we need and verify we have enough. */ - const size_t rgb_width = util::AlignUp(static_cast(width), ImageSizeHorizonalUnit); - const size_t rgb_stride = rgb_width * RgbColorComponentCount; - const size_t rgb_size = rgb_stride * ImageSizeVerticalUnitEncode; - R_UNLESS(work_size >= rgb_size, capsrv::ResultInternalJpegWorkMemoryShortage()); - - /* Return the output to the caller. */ - *out_size = rgb_size; - *out_stride = rgb_stride; - R_SUCCEED(); - } - - void SetupEncodingParameter(JpegLibraryType::jpeg_compress_struct *cinfo, const SoftwareJpegShrinkerInput &input, int quality) { - /* Set parameters. */ - cinfo->image_width = static_cast(input.width / 2); - cinfo->image_height = static_cast(input.height / 2); - cinfo->input_components = RgbColorComponentCount; - cinfo->in_color_space = JpegLibraryType::J_COLOR_SPACE::JCS_RGB; - - /* Set defaults/color space. */ - jpeg_set_defaults(cinfo); - jpeg_set_colorspace(cinfo, JpegLibraryType::J_COLOR_SPACE::JCS_YCbCr); - - /* Configure sampling. */ - /* libjpeg-turbo doesn't actually have this field, as of now. */ - /* cinfo->do_fancy_downsampling = false; */ - cinfo->comp_info[0].h_samp_factor = 2; - cinfo->comp_info[0].v_samp_factor = 1; - cinfo->comp_info[1].h_samp_factor = 1; - cinfo->comp_info[1].v_samp_factor = 1; - cinfo->comp_info[2].h_samp_factor = 1; - cinfo->comp_info[2].v_samp_factor = 1; - - /* Set the quality. */ - jpeg_set_quality(cinfo, quality, true); - - /* Configure remaining parameters. */ - cinfo->dct_method = JpegLibraryType::J_DCT_METHOD::JDCT_ISLOW; - cinfo->optimize_coding = false; - cinfo->write_JFIF_header = true; - } - - } - - Result SoftwareJpegShrinker::ShrinkRgba8(SoftwareJpegShrinkerOutput &output, const SoftwareJpegShrinkerInput &input, int quality, void *work, size_t work_size) { - CAPSRV_ABORT_UNLESS(util::IsAligned(input.width, ImageSizeHorizonalUnit)); - CAPSRV_ABORT_UNLESS(util::IsAligned(input.height, ImageSizeVerticalUnitDecode)); - - const u32 shrunk_width = input.width / 2; - const u32 shrunk_height = input.height / 2; - CAPSRV_ABORT_UNLESS(util::IsAligned(shrunk_width, ImageSizeHorizonalUnit)); - - CAPSRV_ABORT_UNLESS(output.dst != nullptr); - - CAPSRV_ABORT_UNLESS(output.out_width != nullptr); - CAPSRV_ABORT_UNLESS(output.out_height != nullptr); - - /* Determine work buffer extents. */ - char *work_start = static_cast(work); - char *work_end = work_start + work_size; - - /* Determine the buffer extents for our linebuffers. */ - u8 *rgb_buffer = static_cast(static_cast(work_start)); - size_t rgb_buffer_size; - size_t rgb_buffer_stride; - R_TRY(GetRgbBufferSize(std::addressof(rgb_buffer_size), std::addressof(rgb_buffer_stride), input.width, work_size)); - - /* The start of the workbuffer is reserved for linebuffer space. */ - work_start += rgb_buffer_size; - - /* Create our compression structures. */ - JpegLibraryType::jpeg_decompress_struct dcinfo = {}; - JpegLibraryType::jpeg_compress_struct ecinfo = {}; - - /* Here nintendo creates a work buffer structure containing work_start + work_size. */ - /* This seems to be a custom patch for/to libjpeg-turbo. */ - /* It would be desirable for us to mimic this, because it gives Nintendo strong */ - /* fixed memory usage guarantees. */ - /* TODO: Determine if it is feasible for us to recreate this ourselves, */ - /* Either by adding support to the devkitPro libjpeg-turbo portlib or otherwise. */ - AMS_UNUSED(work_end); - - /* Create our error managers. */ - JpegErrorHandler jerr_dc = { .result = ResultSuccess(), }; - JpegErrorHandler jerr_ec = { .result = ResultSuccess(), }; - jerr_dc.error_exit = JpegErrorHandler::HandleError, - jerr_ec.error_exit = JpegErrorHandler::HandleError, - - /* Link our error managers to our compression structures. */ - dcinfo.err = jpeg_std_error(std::addressof(jerr_dc)); - ecinfo.err = jpeg_std_error(std::addressof(jerr_ec)); - - /* Use setjmp, so that on error our handler will longjmp to return an error result. */ - if (setjmp(jerr_ec.jmp_buf) == 0) { - if (setjmp(jerr_dc.jmp_buf) == 0) { - /* Create our decompressor. */ - jpeg_create_decompress(std::addressof(dcinfo)); - ON_SCOPE_EXIT { jpeg_destroy_decompress(std::addressof(dcinfo)); }; - - /* Setup our memory reader, ensure the header is correct. */ - jpeg_mem_src(std::addressof(dcinfo), const_cast(static_cast(input.jpeg)), input.jpeg_size); - R_UNLESS(jpeg_read_header(std::addressof(dcinfo), true) == JPEG_HEADER_OK, capsrv::ResultAlbumInvalidFileData()); - - /* Ensure width and height are correct. */ - R_UNLESS(dcinfo.image_width == input.width, capsrv::ResultAlbumInvalidFileData()); - R_UNLESS(dcinfo.image_height == input.height, capsrv::ResultAlbumInvalidFileData()); - - /* Set output parameters. */ - dcinfo.out_color_space = JpegLibraryType::J_COLOR_SPACE::JCS_RGB; - dcinfo.dct_method = JpegLibraryType::J_DCT_METHOD::JDCT_ISLOW; - dcinfo.do_fancy_upsampling = input.fancy_upsampling; - dcinfo.do_block_smoothing = input.block_smoothing; - dcinfo.scale_num = 1; - dcinfo.scale_denom = 2; - - /* Start decompression. */ - R_UNLESS(jpeg_start_decompress(std::addressof(dcinfo)) == TRUE, capsrv::ResultAlbumInvalidFileData()); - - /* Check the parameters. */ - CAPSRV_ASSERT(dcinfo.output_width == shrunk_width); - CAPSRV_ASSERT(dcinfo.output_height == shrunk_height); - CAPSRV_ASSERT(dcinfo.out_color_components == RgbColorComponentCount); - CAPSRV_ASSERT(dcinfo.output_components == RgbColorComponentCount); - - /* Create our compressor. */ - jpeg_create_compress(std::addressof(ecinfo)); - ON_SCOPE_EXIT { jpeg_destroy_compress(std::addressof(ecinfo)); }; - - /* Setup our memory writer. */ - unsigned long out_size = static_cast(output.dst_size); - jpeg_mem_dest(std::addressof(ecinfo), reinterpret_cast(std::addressof(output.dst)), std::addressof(out_size)); - - /* Setup the encoding parameters. */ - SetupEncodingParameter(std::addressof(ecinfo), input, quality); - - /* Start compression. */ - jpeg_start_compress(std::addressof(ecinfo), true); - - /* Parse the scanlines. */ - { - /* Create our linebuffer structure. */ - JpegLibraryType::JSAMPROW linebuffers[ImageSizeVerticalUnitEncode] = {}; - for (int i = 0; i < ImageSizeVerticalUnitEncode; i++) { - linebuffers[i] = rgb_buffer + rgb_buffer_stride * i; - } - - /* While we still have scanlines, parse! */ - while (dcinfo.output_scanline < shrunk_height) { - /* Determine remaining scanlines. */ - const auto remaining_scanlines = shrunk_height - dcinfo.output_scanline; - const auto cur_max_scanlines = std::min(remaining_scanlines, ImageSizeVerticalUnitEncode); - - /* If we have scanlines to decode, try to do so. */ - auto writable_scanlines = 0; - while (writable_scanlines < cur_max_scanlines) { - const auto decoded = jpeg_read_scanlines(std::addressof(dcinfo), linebuffers + writable_scanlines, ImageSizeVerticalUnitDecode); - CAPSRV_ASSERT(decoded <= ImageSizeVerticalUnitDecode / 2); - - writable_scanlines += decoded; - } - - /* If we have scanlines to write, try to do so. */ - jpeg_write_scanlines(std::addressof(ecinfo), linebuffers, writable_scanlines); - } - } - - /* Finish the decompression. */ - R_UNLESS(jpeg_finish_decompress(std::addressof(dcinfo)) == TRUE, capsrv::ResultAlbumInvalidFileData()); - - /* Finish the compression. */ - jpeg_finish_compress(std::addressof(ecinfo)); - - /* Set the output size. */ - *output.out_size = out_size; - } else { - /* Some unknown error was caught by our handler. */ - R_THROW(capsrv::ResultAlbumInvalidFileData()); - } - } else { - /* Return the encoding result. */ - R_THROW(jerr_ec.result); - } - - /* Write the size we decoded to output. */ - *output.out_width = static_cast(dcinfo.output_width); - *output.out_width = static_cast(dcinfo.output_height); - - R_SUCCEED(); - } - -} diff --git a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp deleted file mode 100644 index a2774b20b..000000000 --- a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp +++ /dev/null @@ -1,43 +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 . - */ -#pragma once -#include - -namespace ams::capsrv::server::jpeg { - - struct SoftwareJpegShrinkerInput { - const void *jpeg; - size_t jpeg_size; - u32 width; - u32 height; - bool fancy_upsampling; - bool block_smoothing; - }; - - struct SoftwareJpegShrinkerOutput { - u64 *out_size; - s32 *out_width; - s32 *out_height; - void *dst; - size_t dst_size; - }; - - class SoftwareJpegShrinker { - public: - static Result ShrinkRgba8(SoftwareJpegShrinkerOutput &output, const SoftwareJpegShrinkerInput &input, int quality, void *work, size_t work_size); - }; - -} \ No newline at end of file diff --git a/libraries/libstratosphere/source/diag/diag_log_impl.hpp b/libraries/libstratosphere/source/diag/diag_log_impl.hpp index 4a504375f..05b625307 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 = 0x100; + constexpr inline size_t DebugPrintBufferLength = 0x80; } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp index a71c3c6f5..45cae0b4a 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp @@ -48,7 +48,7 @@ namespace ams::erpt::srv { ON_SCOPE_EXIT { Deallocate(hdr); }; hdr->magic = HeaderMagic; - hdr->field_type = static_cast(ConvertFieldToType(field_id)); + hdr->field_type = static_cast(FieldToTypeMap[field_id]); hdr->element_count = arr_size; hdr->reserved = 0; @@ -97,7 +97,7 @@ namespace ams::erpt::srv { } static Result AddField(Report *report, FieldId field_id, char *str, u32 len) { - if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { + if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, str, len)); } else { R_RETURN(Formatter::AddField(report, field_id, str, len)); @@ -105,7 +105,7 @@ namespace ams::erpt::srv { } static Result AddField(Report *report, FieldId field_id, u8 *bin, u32 len) { - if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { + if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, bin, len)); } else { R_RETURN(Formatter::AddField(report, field_id, bin, len)); @@ -114,7 +114,7 @@ namespace ams::erpt::srv { template static Result AddField(Report *report, FieldId field_id, T *arr, u32 len) { - if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { + if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, arr, len)); } else { R_RETURN(Formatter::AddField(report, field_id, arr, len)); 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 77a39a5c5..4bc533d22 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp @@ -38,7 +38,7 @@ namespace ams::erpt::srv { R_RETURN(Context::SubmitContext(ctx, data, data_size)); } - Result ContextImpl::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 ContextImpl::CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); const ReportMetaData *meta = reinterpret_cast(meta_buffer.GetPointer()); @@ -50,19 +50,15 @@ 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, nullptr)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0)); ManagerImpl::NotifyAll(); R_SUCCEED(); } - Result ContextImpl::CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result) { - R_RETURN(this->CreateReport(report_type, ctx_buffer, data_buffer, meta_buffer, result, erpt::srv::MakeNoCreateReportOptionFlags())); - } - Result ContextImpl::CreateReportV0(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer) { - R_RETURN(this->CreateReportV1(report_type, ctx_buffer, data_buffer, meta_buffer, ResultSuccess())); + R_RETURN(this->CreateReport(report_type, ctx_buffer, data_buffer, meta_buffer, ResultSuccess())); } Result ContextImpl::SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time_point) { @@ -142,12 +138,7 @@ 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) { + 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) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); const u32 ctx_size = static_cast(ctx_buffer.GetSize()); @@ -159,42 +150,15 @@ 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, nullptr)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments)); ManagerImpl::NotifyAll(); R_SUCCEED(); } - Result ContextImpl::CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result) { - R_RETURN(this->CreateReportWithAttachments(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, result, erpt::srv::MakeNoCreateReportOptionFlags())); - } - Result ContextImpl::CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer) { - 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(); + R_RETURN(this->CreateReportWithAttachments(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); } Result ContextImpl::RegisterRunningApplet(ncm::ProgramId 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 cada2ceb2..4fa816f3c 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp @@ -31,12 +31,8 @@ namespace ams::erpt::srv { Result ClearApplicationLaunchTime(); Result SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); Result CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer); - Result CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result); - 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 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); + 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); 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_context_record.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp index 23dde0b33..0acc1cabf 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp @@ -69,17 +69,17 @@ namespace ams::erpt::srv { auto guard = SCOPE_GUARD { m_ctx.field_count = 0; }; - R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); - R_UNLESS(FindCategoryIndex(m_ctx.category).has_value(), erpt::ResultInvalidArgument()); + R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.category && m_ctx.category < CategoryId_Count, erpt::ResultInvalidArgument()); for (u32 i = 0; i < m_ctx.field_count; i++) { m_ctx.fields[i] = ctx_ptr->fields[i]; - R_UNLESS(FindFieldIndex(m_ctx.fields[i].id).has_value(), erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument()); R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); - R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch()); - R_UNLESS(m_ctx.category == ConvertFieldToCategory(m_ctx.fields[i].id), erpt::ResultFieldCategoryMismatch()); + R_UNLESS(m_ctx.fields[i].type == FieldToTypeMap[m_ctx.fields[i].id], erpt::ResultFieldTypeMismatch()); + R_UNLESS(m_ctx.category == FieldToCategoryMap[m_ctx.fields[i].id], erpt::ResultFieldCategoryMismatch()); if (IsArrayFieldType(m_ctx.fields[i].type)) { const u32 start_idx = m_ctx.fields[i].value_array.start_idx; 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 c41e04f36..a6a622f71 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(), nullptr)); + R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp index fcdb4836a..b50712be3 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp @@ -62,10 +62,7 @@ namespace ams::erpt::srv { static Result AddId(Report *report, FieldId field_id) { static_assert(MaxFieldStringSize < ElementSize_256); - const auto index = FindFieldIndex(field_id); - AMS_ASSERT(index.has_value()); - - R_TRY(AddStringValue(report, FieldString[index.value()], strnlen(FieldString[index.value()], MaxFieldStringSize))); + R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp deleted file mode 100644 index 5d9d7ad17..000000000 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp +++ /dev/null @@ -1,23 +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 . - */ -#pragma once -#include - -namespace ams::erpt::srv { - - Result SubmitFsInfo(); - -} diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp deleted file mode 100644 index 1b7840783..000000000 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ /dev/null @@ -1,499 +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 . - */ -#include -#include "erpt_srv_fs_info.hpp" -#include "erpt_srv_context_record.hpp" -#include "erpt_srv_context.hpp" - -namespace ams::erpt::srv { - - namespace { - - Result SubmitMmcDetailInfo() { - /* Submit the mmc cid. */ - { - u8 mmc_cid[fs::MmcCidSize] = {}; - if (R_SUCCEEDED(fs::GetMmcCid(mmc_cid, sizeof(mmc_cid)))) { - /* Clear the serial number from the cid. */ - fs::ClearMmcCidSerialNumber(mmc_cid); - - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDTypeInfo, sizeof(mmc_cid)); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add the cid. */ - R_ABORT_UNLESS(record->Add(FieldId_NANDType, mmc_cid, sizeof(mmc_cid))); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - /* Submit the mmc speed mode. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDSpeedModeInfo, 0x20); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Get the speed mode. */ - fs::MmcSpeedMode speed_mode{}; - const auto res = fs::GetMmcSpeedMode(std::addressof(speed_mode)); - if (R_SUCCEEDED(res)) { - const char *speed_mode_name = "None"; - switch (speed_mode) { - case fs::MmcSpeedMode_Identification: - speed_mode_name = "Identification"; - break; - case fs::MmcSpeedMode_LegacySpeed: - speed_mode_name = "LegacySpeed"; - break; - case fs::MmcSpeedMode_HighSpeed: - speed_mode_name = "HighSpeed"; - break; - case fs::MmcSpeedMode_Hs200: - speed_mode_name = "Hs200"; - break; - case fs::MmcSpeedMode_Hs400: - speed_mode_name = "Hs400"; - break; - case fs::MmcSpeedMode_Unknown: - speed_mode_name = "Unknown"; - break; - default: - speed_mode_name = "UnDefined"; - break; - } - - R_ABORT_UNLESS(record->Add(FieldId_NANDSpeedMode, speed_mode_name, std::strlen(speed_mode_name))); - } else { - /* Getting speed mode failed, so add the result. */ - char res_str[0x20]; - util::SNPrintf(res_str, sizeof(res_str), "0x%08X", res.GetValue()); - R_ABORT_UNLESS(record->Add(FieldId_NANDSpeedMode, res_str, std::strlen(res_str))); - } - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - /* Submit the mmc extended csd. */ - { - u8 mmc_csd[fs::MmcExtendedCsdSize] = {}; - if (R_SUCCEEDED(fs::GetMmcExtendedCsd(mmc_csd, sizeof(mmc_csd)))) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDExtendedCsd, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields from the csd. */ - R_ABORT_UNLESS(record->Add(FieldId_NANDPreEolInfo, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetReEolInfo]))); - R_ABORT_UNLESS(record->Add(FieldId_NANDDeviceLifeTimeEstTypA, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetDeviceLifeTimeEstTypA]))); - R_ABORT_UNLESS(record->Add(FieldId_NANDDeviceLifeTimeEstTypB, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetDeviceLifeTimeEstTypB]))); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - /* Submit the mmc patrol count. */ - { - u32 count = 0; - if (R_SUCCEEDED(fs::GetMmcPatrolCount(std::addressof(count)))) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDPatrolInfo, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add the count. */ - R_ABORT_UNLESS(record->Add(FieldId_NANDPatrolCount, count)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - R_SUCCEED(); - } - - Result SubmitMmcErrorInfo() { - /* Get the mmc error info. */ - fs::StorageErrorInfo sei = {}; - char log_buffer[erpt::ArrayBufferSizeDefault] = {}; - size_t log_size = 0; - if (R_SUCCEEDED(fs::GetAndClearMmcErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { - /* Submit the error info. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDErrorInfo, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationFailures, sei.num_activation_failures)); - R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationErrorCorrections, sei.num_activation_error_corrections)); - R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteFailures, sei.num_read_write_failures)); - R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - /* If we have a log, submit it. */ - if (log_size > 0) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_NANDDriverLog, log_size); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_NANDErrorLog, log_buffer, log_size)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - R_SUCCEED(); - } - - Result SubmitSdCardDetailInfo() { - /* Submit the sd card cid. */ - { - u8 sd_cid[fs::SdCardCidSize] = {}; - if (R_SUCCEEDED(fs::GetSdCardCid(sd_cid, sizeof(sd_cid)))) { - /* Clear the serial number from the cid. */ - fs::ClearSdCardCidSerialNumber(sd_cid); - - /* Create a record. */ - auto record = std::make_unique(CategoryId_MicroSDTypeInfo, sizeof(sd_cid)); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add the cid. */ - R_ABORT_UNLESS(record->Add(FieldId_MicroSDType, sd_cid, sizeof(sd_cid))); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - /* Submit the sd card speed mode. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_MicroSDSpeedModeInfo, 0x20); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Get the speed mode. */ - fs::SdCardSpeedMode speed_mode{}; - const auto res = fs::GetSdCardSpeedMode(std::addressof(speed_mode)); - if (R_SUCCEEDED(res)) { - const char *speed_mode_name = "None"; - switch (speed_mode) { - case fs::SdCardSpeedMode_Identification: - speed_mode_name = "Identification"; - break; - case fs::SdCardSpeedMode_DefaultSpeed: - speed_mode_name = "DefaultSpeed"; - break; - case fs::SdCardSpeedMode_HighSpeed: - speed_mode_name = "HighSpeed"; - break; - case fs::SdCardSpeedMode_Sdr12: - speed_mode_name = "Sdr12"; - break; - case fs::SdCardSpeedMode_Sdr25: - speed_mode_name = "Sdr25"; - break; - case fs::SdCardSpeedMode_Sdr50: - speed_mode_name = "Sdr50"; - break; - case fs::SdCardSpeedMode_Sdr104: - speed_mode_name = "Sdr104"; - break; - case fs::SdCardSpeedMode_Ddr50: - speed_mode_name = "Ddr50"; - break; - case fs::SdCardSpeedMode_Unknown: - speed_mode_name = "Unknown"; - break; - default: - speed_mode_name = "UnDefined"; - break; - } - - R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, speed_mode_name, std::strlen(speed_mode_name))); - } else { - /* Getting speed mode failed, so add the result. */ - char res_str[0x20]; - util::SNPrintf(res_str, sizeof(res_str), "0x%08X", res.GetValue()); - R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, res_str, std::strlen(res_str))); - } - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - /* Submit the area sizes. */ - { - s64 user_area_size = 0; - s64 prot_area_size = 0; - const Result res_user = fs::GetSdCardUserAreaSize(std::addressof(user_area_size)); - const Result res_prot = fs::GetSdCardProtectedAreaSize(std::addressof(prot_area_size)); - if (R_SUCCEEDED(res_user) || R_SUCCEEDED(res_prot)) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_SdCardSizeSpec, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add sizes. */ - if (R_SUCCEEDED(res_user)) { - R_ABORT_UNLESS(record->Add(FieldId_SdCardUserAreaSize, user_area_size)); - } - if (R_SUCCEEDED(res_prot)) { - R_ABORT_UNLESS(record->Add(FieldId_SdCardProtectedAreaSize, prot_area_size)); - } - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - R_SUCCEED(); - } - - Result SubmitSdCardErrorInfo() { - /* Get the sd card error info. */ - fs::StorageErrorInfo sei = {}; - char log_buffer[erpt::ArrayBufferSizeDefault] = {}; - size_t log_size = 0; - if (R_SUCCEEDED(fs::GetAndClearSdCardErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { - /* Submit the error info. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_SdCardErrorInfo, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationFailures, sei.num_activation_failures)); - R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationErrorCorrections, sei.num_activation_error_corrections)); - R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteFailures, sei.num_read_write_failures)); - R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - /* If we have a log, submit it. */ - if (log_size > 0) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_SdCardDriverLog, log_size); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_SdCardErrorLog, log_buffer, log_size)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - R_SUCCEED(); - } - - Result SubmitGameCardDetailInfo() { - /* Create a record. */ - auto record = std::make_unique(CategoryId_GameCardCIDInfo, fs::GameCardCidSize + fs::GameCardDeviceIdSize); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add the game card cid. */ - { - u8 gc_cid[fs::GameCardCidSize] = {}; - if (fs::IsGameCardInserted() && R_SUCCEEDED(fs::GetGameCardCid(gc_cid, sizeof(gc_cid)))) { - /* Add the cid. */ - R_ABORT_UNLESS(record->Add(FieldId_GameCardCID, gc_cid, sizeof(gc_cid))); - } - } - - /* Add the game card device id. */ - { - u8 gc_device_id[fs::GameCardDeviceIdSize] = {}; - if (fs::IsGameCardInserted() && R_SUCCEEDED(fs::GetGameCardDeviceId(gc_device_id, sizeof(gc_device_id)))) { - /* Add the cid. */ - R_ABORT_UNLESS(record->Add(FieldId_GameCardDeviceId, gc_device_id, sizeof(gc_device_id))); - } - } - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - - R_SUCCEED(); - } - - Result SubmitGameCardErrorInfo() { - /* Get the game card error info. */ - fs::GameCardErrorReportInfo ei = {}; - if (R_SUCCEEDED(fs::GetGameCardErrorReportInfo(std::addressof(ei)))) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_GameCardErrorInfo, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_GameCardCrcErrorCount, static_cast(ei.game_card_crc_error_num))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicCrcErrorCount, static_cast(ei.asic_crc_error_num))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardRefreshCount, static_cast(ei.refresh_num))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardReadRetryCount, static_cast(ei.retry_limit_out_num))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardTimeoutRetryErrorCount, static_cast(ei.timeout_retry_num))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardInsertionCount, static_cast(ei.insertion_count))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardRemovalCount, static_cast(ei.removal_count))); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicInitializeCount, ei.initialize_count)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeCount, ei.asic_reinitialize_num)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeFailureCount, ei.asic_reinitialize_failure_num)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeFailureDetail, ei.asic_reinitialize_failure_detail)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardRefreshSuccessCount, ei.refresh_succeeded_count)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAwakenCount, ei.awaken_count)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardAwakenFailureCount, ei.awaken_failure_num)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromInsert, ei.read_count_from_insert)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address)); - R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - R_SUCCEED(); - } - - Result SubmitFileSystemErrorInfo() { - /* Get the fsp error info. */ - fs::FileSystemProxyErrorInfo ei = {}; - if (R_SUCCEEDED(fs::GetAndClearFileSystemProxyErrorInfo(std::addressof(ei)))) { - /* Submit FsProxyErrorInfo. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_FsProxyErrorInfo, fat::FatErrorNameMaxLength); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_FsRemountForDataCorruptCount, ei.rom_fs_remount_for_data_corruption_count)); - R_ABORT_UNLESS(record->Add(FieldId_FsRemountForDataCorruptRetryOutCount, ei.rom_fs_unrecoverable_data_corruption_by_remount_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsError, ei.fat_fs_error.error)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsExtraError, ei.fat_fs_error.extra_error)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsErrorDrive, ei.fat_fs_error.drive_id)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsErrorName, ei.fat_fs_error.name, fat::FatErrorNameMaxLength)); - - R_ABORT_UNLESS(record->Add(FieldId_FsRecoveredByInvalidateCacheCount, ei.rom_fs_recovered_by_invalidate_cache_count)); - R_ABORT_UNLESS(record->Add(FieldId_FsSaveDataIndexCount, ei.save_data_index_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFilePeakOpenCount, ei.bis_system_fat_report_info_1.open_file_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemDirectoryPeakOpenCount, ei.bis_system_fat_report_info_1.open_directory_peak_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFilePeakOpenCount, ei.bis_user_fat_report_info_1.open_file_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserDirectoryPeakOpenCount, ei.bis_user_fat_report_info_1.open_directory_peak_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardFilePeakOpenCount, ei.sd_card_fat_report_info_1.open_file_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardDirectoryPeakOpenCount, ei.sd_card_fat_report_info_1.open_directory_peak_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemUniqueFileEntryPeakOpenCount, ei.bis_system_fat_report_info_2.open_unique_file_entry_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, ei.bis_system_fat_report_info_2.open_unique_directory_entry_peak_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserUniqueFileEntryPeakOpenCount, ei.bis_user_fat_report_info_2.open_unique_file_entry_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserUniqueDirectoryEntryPeakOpenCount, ei.bis_user_fat_report_info_2.open_unique_directory_entry_peak_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardUniqueFileEntryPeakOpenCount, ei.sd_card_fat_report_info_2.open_unique_file_entry_peak_count)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardUniqueDirectoryEntryPeakOpenCount, ei.sd_card_fat_report_info_2.open_unique_directory_entry_peak_count)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - /* Submit FsProxyErrorInfo2. */ - { - /* Create a record. */ - auto record = std::make_unique(CategoryId_FsProxyErrorInfo2, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_FsDeepRetryStartCount, ei.rom_fs_deep_retry_start_count)); - R_ABORT_UNLESS(record->Add(FieldId_FsUnrecoverableByGameCardAccessFailedCount, ei.rom_fs_unrecoverable_by_game_card_access_failed_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatSafeControlResult, static_cast(ei.bis_system_fat_safe_info.result))); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatErrorNumber, ei.bis_system_fat_safe_info.error_number)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatSafeErrorNumber, ei.bis_system_fat_safe_info.safe_error_number)); - - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatSafeControlResult, static_cast(ei.bis_user_fat_safe_info.result))); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatErrorNumber, ei.bis_user_fat_safe_info.error_number)); - R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatSafeErrorNumber, ei.bis_user_fat_safe_info.safe_error_number)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - } - - R_SUCCEED(); - } - - Result SubmitMemoryReportInfo() { - /* Get the memory report info. */ - fs::MemoryReportInfo mri = {}; - if (R_SUCCEEDED(fs::GetAndClearMemoryReportInfo(std::addressof(mri)))) { - /* Create a record. */ - auto record = std::make_unique(CategoryId_FsMemoryInfo, 0); - R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - - /* Add fields. */ - R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferPeakFreeSize, mri.pooled_buffer_peak_free_size)); - R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferRetriedCount, mri.pooled_buffer_retried_count)); - R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferReduceAllocationCount, mri.pooled_buffer_reduce_allocation_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerPeakFreeSize, mri.buffer_manager_peak_free_size)); - R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerRetriedCount, mri.buffer_manager_retried_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FsExpHeapPeakFreeSize, mri.exp_heap_peak_free_size)); - - R_ABORT_UNLESS(record->Add(FieldId_FsBufferPoolPeakFreeSize, mri.buffer_pool_peak_free_size)); - - R_ABORT_UNLESS(record->Add(FieldId_FsPatrolReadAllocateBufferSuccessCount, mri.patrol_read_allocate_buffer_success_count)); - R_ABORT_UNLESS(record->Add(FieldId_FsPatrolReadAllocateBufferFailureCount, mri.patrol_read_allocate_buffer_failure_count)); - - R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerPeakTotalAllocatableSize, mri.buffer_manager_peak_total_allocatable_size)); - - R_ABORT_UNLESS(record->Add(FieldId_FsBufferPoolMaxAllocateSize, mri.buffer_pool_max_allocate_size)); - - R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, mri.pooled_buffer_failed_ideal_allocation_count_on_async_access)); - - /* Submit the record. */ - R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); - } - - R_SUCCEED(); - } - - } - - Result SubmitFsInfo() { - /* Temporarily disable auto-abort. */ - fs::ScopedAutoAbortDisabler aad; - - /* Submit various FS info. */ - R_TRY(SubmitMmcDetailInfo()); - R_TRY(SubmitMmcErrorInfo()); - R_TRY(SubmitSdCardDetailInfo()); - R_TRY(SubmitSdCardErrorInfo()); - R_TRY(SubmitGameCardDetailInfo()); - R_TRY(SubmitGameCardErrorInfo()); - R_TRY(SubmitFileSystemErrorInfo()); - R_TRY(SubmitMemoryReportInfo()); - - 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 84dd89f53..446ccafca 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(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)); + Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) { + R_RETURN(JournalForAttachments::GetAttachmentList(out, 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 16011e75a..5adfa87c0 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(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); + static Result GetAttachmentList(AttachmentList *out, 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(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); + static Result GetAttachmentList(AttachmentList *out, 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 402951380..4a7c75570 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,19 +77,14 @@ namespace ams::erpt::srv { R_SUCCEED(); } - 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()); - } - + Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) { u32 count = 0; - for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < max_out_infos; it++) { + for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < util::size(out->attachments); it++) { if (report_id == it->m_info.owner_report_id) { - out_infos[count++] = it->m_info; + out->attachments[count++] = it->m_info; } } - *out_count = count; + out->attachment_count = count; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 8fb682244..6f23bde32 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -105,8 +105,8 @@ namespace ams::erpt::srv { g_sf_allocator.Attach(g_heap_handle); - for (const auto category_id : CategoryIndexToCategoryIdMap) { - Context *ctx = new Context(category_id); + for (auto i = 0; i < CategoryId_Count; i++) { + Context *ctx = new Context(static_cast(i)); AMS_ABORT_UNLESS(ctx != nullptr); } 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 2130a5200..144507e42 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp @@ -86,23 +86,10 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result ManagerImpl::GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { + Result ManagerImpl::GetAttachmentList(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument()); - 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(); + R_RETURN(Journal::GetAttachmentList(reinterpret_cast(out_list.GetPointer()), report_id)); } } 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 24046b29b..bbf0c254e 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp @@ -34,9 +34,7 @@ namespace ams::erpt::srv { Result CleanupReports(); Result DeleteReport(const ReportId &report_id); Result GetStorageUsageStatistics(ams::sf::Out out); - 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); + Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id); }; 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 a9a2871c6..2efa84820 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -19,7 +19,6 @@ #include "erpt_srv_journal.hpp" #include "erpt_srv_context_record.hpp" #include "erpt_srv_context.hpp" -#include "erpt_srv_fs_info.hpp" namespace ams::erpt::srv { @@ -165,7 +164,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \ + if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \ return; \ } \ } while (0) @@ -204,7 +203,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \ + if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \ return; \ } \ } while (0) @@ -277,7 +276,7 @@ namespace ams::erpt::srv { void SaveSyslogReportIfRequired(const ContextEntry *ctx, const ReportId &report_id) { bool needs_save_syslog = true; for (u32 i = 0; i < ctx->field_count; i++) { - static_assert(FieldIndexToTypeMap[*FindFieldIndex(FieldId_HasSyslogFlag)] == FieldType_Bool); + static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool); if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) { needs_save_syslog = false; break; @@ -414,7 +413,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, const ReportId *specified_report_id) { + 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) { /* Create a context record for the report. */ auto record = std::make_unique(); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); @@ -423,10 +422,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, specified_report_id)); + R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments)); } - 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) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments) { /* Clear the automatic categories, when we're done with our report. */ ON_SCOPE_EXIT { Context::ClearContext(CategoryId_ErrorInfo); @@ -444,7 +443,7 @@ namespace ams::erpt::srv { R_TRY(SubmitReportDefaults(ctx)); /* Generate report id. */ - const ReportId report_id = specified_report_id ? *specified_report_id : ReportId{ .uuid = util::GenerateUuid() }; + const ReportId report_id = { .uuid = util::GenerateUuid() }; /* Get posix timestamps. */ time::PosixTime timestamp_user; @@ -458,7 +457,7 @@ namespace ams::erpt::srv { SaveSyslogReportIfRequired(ctx, report_id); /* Submit report contexts. */ - R_TRY(SubmitReportContexts(report_id, type, ctx_result, std::move(record), timestamp_user, timestamp_network, flags)); + R_TRY(SubmitReportContexts(report_id, type, ctx_result, std::move(record), timestamp_user, timestamp_network)); /* Link attachments to the report. */ R_TRY(LinkAttachments(report_id, attachments, num_attachments)); @@ -469,7 +468,7 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result Reporter::SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime ×tamp_user, const time::PosixTime ×tamp_network, erpt::CreateReportOptionFlagSet flags) { + Result Reporter::SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime ×tamp_user, const time::PosixTime ×tamp_network) { /* Create automatic record. */ auto auto_record = std::make_unique(CategoryId_ErrorInfoAuto, 0x300); R_UNLESS(auto_record != nullptr, erpt::ResultOutOfMemory()); @@ -531,17 +530,6 @@ namespace ams::erpt::srv { SubmitResourceLimitContexts(); #endif - /* If we should, submit fs info. */ - #if defined(ATMOSPHERE_OS_HORIZON) - if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test()) { - /* NOTE: Nintendo ignores the result of this call. */ - SubmitFsInfo(); - } - #else - AMS_UNUSED(flags); - #endif - - R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp index f5db475ec..ca6fd256e 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp @@ -56,10 +56,10 @@ namespace ams::erpt::srv { static void SetRedirectNewReportsToSdCard(bool en) { s_redirect_new_reports = en; } 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); + 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); 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, 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); + 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); + static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments); }; } diff --git a/libraries/libstratosphere/source/fs/fs_api.cpp b/libraries/libstratosphere/source/fs/fs_api.cpp index c548fc674..f04e3049b 100644 --- a/libraries/libstratosphere/source/fs/fs_api.cpp +++ b/libraries/libstratosphere/source/fs/fs_api.cpp @@ -23,8 +23,8 @@ namespace ams::fs { #if defined(ATMOSPHERE_OS_HORIZON) namespace { - alignas(0x10) constinit std::byte g_fsp_service_object_buffer[0x80] = {}; - alignas(0x10) constinit std::byte g_fsp_ldr_service_object_buffer[0x80] = {}; + constinit std::aligned_storage_t<0x80> g_fsp_service_object_buffer; + constinit std::aligned_storage_t<0x80> g_fsp_ldr_service_object_buffer; constinit bool g_use_static_fsp_service_object_buffer = false; constinit bool g_use_static_fsp_ldr_service_object_buffer = false; diff --git a/libraries/libstratosphere/source/fs/fs_code.cpp b/libraries/libstratosphere/source/fs/fs_code.cpp index e7c694e0f..23fa37a13 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, ncm::StorageId storage_id) { + Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { /* Print a path suitable for the remote service. */ fssrv::sf::Path sf_path; R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path)); @@ -79,11 +79,7 @@ namespace ams::fs { R_TRY(fsp->SetCurrentProcess({})); sf::SharedPointer fs; - 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)); - } + R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), out_verification_data, sf_path, attr, program_id)); /* Allocate a new filesystem wrapper. */ auto fsa = std::make_unique(std::move(fs)); @@ -152,7 +148,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, ncm::StorageId storage_id) { + Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { /* If we can open an sd card code fs, use it. */ R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id))); @@ -160,7 +156,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, storage_id)); + R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id)); } Result OpenHblCodeFileSystemImpl(std::unique_ptr *out) { @@ -338,12 +334,11 @@ 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, ncm::StorageId storage_id, bool is_hbl, bool is_specific) { + Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { AMS_ABORT_UNLESS(!m_initialized); /* If we're hbl, we need to open a hbl fs. */ @@ -355,11 +350,10 @@ namespace ams::fs { /* Open the code filesystem. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id, storage_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id)); m_code_fs.emplace(std::move(fsa), program_id, is_specific); - m_program_id = program_id; - m_storage_id = storage_id; + m_program_id = program_id; m_initialized = true; R_SUCCEED(); @@ -392,7 +386,7 @@ namespace ams::fs { } - Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -405,7 +399,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); + R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id)); /* Register. */ R_RETURN(fsa::Register(name, std::move(fsa))); @@ -420,7 +414,7 @@ namespace ams::fs { R_SUCCEED(); } - 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 MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -436,7 +430,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, storage_id, is_hbl, is_specific)); + R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, is_hbl, is_specific)); /* Register. */ R_RETURN(fsa::Register(name, std::move(ams_code_fs))); @@ -451,7 +445,7 @@ namespace ams::fs { R_SUCCEED(); } - Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -464,7 +458,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_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_error_info.cpp b/libraries/libstratosphere/source/fs/fs_error_info.cpp deleted file mode 100644 index a6dab78e4..000000000 --- a/libraries/libstratosphere/source/fs/fs_error_info.cpp +++ /dev/null @@ -1,35 +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 . - */ -#include -#include "fsa/fs_mount_utils.hpp" -#include "impl/fs_file_system_proxy_service_object.hpp" -#include "impl/fs_file_system_service_object_adapter.hpp" - -namespace ams::fs { - - Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Get the error info. */ - AMS_FS_R_TRY(fsp->GetAndClearErrorInfo(out)); - - R_SUCCEED(); - } - -} diff --git a/libraries/libstratosphere/source/fs/fs_game_card.cpp b/libraries/libstratosphere/source/fs/fs_game_card.cpp index 08e88ecb1..023185c62 100644 --- a/libraries/libstratosphere/source/fs/fs_game_card.cpp +++ b/libraries/libstratosphere/source/fs/fs_game_card.cpp @@ -100,65 +100,4 @@ namespace ams::fs { R_SUCCEED(); } - bool IsGameCardInserted() { - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_ABORT_UNLESS(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get insertion status. */ - bool inserted; - AMS_FS_R_ABORT_UNLESS(device_operator->IsGameCardInserted(std::addressof(inserted))); - - return inserted; - } - - Result GetGameCardCid(void *dst, size_t size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(size >= sizeof(gc::GameCardIdSet), fs::ResultInvalidSize()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the id set. */ - gc::GameCardIdSet gc_id_set; - AMS_FS_R_TRY(device_operator->GetGameCardIdSet(sf::OutBuffer(std::addressof(gc_id_set), sizeof(gc_id_set)), static_cast(sizeof(gc_id_set)))); - - /* Copy the id set to output. */ - std::memcpy(dst, std::addressof(gc_id_set), sizeof(gc_id_set)); - - R_SUCCEED(); - - } - - Result GetGameCardDeviceId(void *dst, size_t size) { - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the cid. */ - AMS_FS_R_TRY(device_operator->GetGameCardDeviceId(sf::OutBuffer(dst, size), static_cast(size))); - - R_SUCCEED(); - } - - Result GetGameCardErrorReportInfo(GameCardErrorReportInfo *out) { - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the error report info. */ - AMS_FS_R_TRY(device_operator->GetGameCardErrorReportInfo(out)); - - R_SUCCEED(); - } - } diff --git a/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp b/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp deleted file mode 100644 index f858aea33..000000000 --- a/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp +++ /dev/null @@ -1,35 +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 . - */ -#include -#include "fsa/fs_mount_utils.hpp" -#include "impl/fs_file_system_proxy_service_object.hpp" -#include "impl/fs_file_system_service_object_adapter.hpp" - -namespace ams::fs { - - Result GetAndClearMemoryReportInfo(MemoryReportInfo *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Get the memory report info. */ - AMS_FS_R_TRY(fsp->GetAndClearMemoryReportInfo(out)); - - R_SUCCEED(); - } - -} diff --git a/libraries/libstratosphere/source/fs/fs_mmc.cpp b/libraries/libstratosphere/source/fs/fs_mmc.cpp deleted file mode 100644 index f14364b92..000000000 --- a/libraries/libstratosphere/source/fs/fs_mmc.cpp +++ /dev/null @@ -1,109 +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 . - */ -#include -#include "fsa/fs_mount_utils.hpp" -#include "impl/fs_file_system_proxy_service_object.hpp" -#include "impl/fs_file_system_service_object_adapter.hpp" - -namespace ams::fs { - - Result GetMmcCid(void *dst, size_t size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the cid. */ - AMS_FS_R_TRY(device_operator->GetMmcCid(sf::OutBuffer(dst, size), static_cast(size))); - - R_SUCCEED(); - } - - Result GetMmcSpeedMode(MmcSpeedMode *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the speed mode. */ - s64 speed_mode = 0; - AMS_FS_R_TRY(device_operator->GetMmcSpeedMode(std::addressof(speed_mode))); - - *out = static_cast(speed_mode); - R_SUCCEED(); - } - - Result GetMmcPatrolCount(u32 *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the patrol count. */ - AMS_FS_R_TRY(device_operator->GetMmcPatrolCount(out)); - - R_SUCCEED(); - } - - Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); - AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); - AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the error info. */ - s64 log_size = 0; - AMS_FS_R_TRY(device_operator->GetAndClearMmcErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); - - *out_log_size = static_cast(log_size); - R_SUCCEED(); - } - - Result GetMmcExtendedCsd(void *dst, size_t size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the csd. */ - AMS_FS_R_TRY(device_operator->GetMmcExtendedCsd(sf::OutBuffer(dst, size), static_cast(size))); - - R_SUCCEED(); - } - -} diff --git a/libraries/libstratosphere/source/fs/fs_program_id.cpp b/libraries/libstratosphere/source/fs/fs_program_id.cpp deleted file mode 100644 index 3ef64dae7..000000000 --- a/libraries/libstratosphere/source/fs/fs_program_id.cpp +++ /dev/null @@ -1,36 +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 . - */ -#include -#include -#include "impl/fs_file_system_proxy_service_object.hpp" - -namespace ams::fs { - - Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr) { - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - AMS_FS_R_UNLESS(path != nullptr, fs::ResultNullptrArgument()); - - /* Convert the path for fsp. */ - fssrv::sf::FspPath sf_path; - R_TRY(fs::ConvertToFspPath(std::addressof(sf_path), path)); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - AMS_FS_R_TRY(fsp->GetProgramId(out, sf_path, attr)); - - R_SUCCEED(); - } - -} \ No newline at end of file diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp index 6cfcd8ab4..f7eda97ad 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp @@ -320,10 +320,6 @@ namespace ams::fs { AMS_ABORT("TODO"); } - Result GetProgramId(ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr) { - static_assert(sizeof(ncm::ProgramId) == sizeof(u64)); - R_RETURN(fsGetProgramId(reinterpret_cast(out.GetPointer()), path.str, static_cast<::FsContentAttributes>(static_cast(attr)))); - } Result GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path) { static_assert(sizeof(RightsId) == sizeof(::FsRightsId)); @@ -389,11 +385,6 @@ namespace ams::fs { /* ... */ - Result GetAndClearErrorInfo(ams::sf::Out out) { - static_assert(sizeof(fs::FileSystemProxyErrorInfo) == sizeof(::FsFileSystemProxyErrorInfo)); - R_RETURN(::fsGetAndClearErrorInfo(reinterpret_cast<::FsFileSystemProxyErrorInfo *>(out.GetPointer()))); - } - Result RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count) { AMS_ABORT("TODO"); } @@ -434,11 +425,6 @@ namespace ams::fs { AMS_ABORT("TODO"); } - Result GetAndClearMemoryReportInfo(ams::sf::Out out) { - static_assert(sizeof(fs::MemoryReportInfo) == sizeof(::FsMemoryReportInfo)); - R_RETURN(::fsGetAndClearMemoryReportInfo(reinterpret_cast<::FsMemoryReportInfo *>(out.GetPointer()))); - } - /* ... */ Result GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count) { 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 528b1a92b..fff9ba88c 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, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); @@ -41,31 +41,15 @@ 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, ::NcmStorageId_None, 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, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); } - 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, 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, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); - - out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); - R_SUCCEED(); - } - - 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, ::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))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, 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_romfs_filesystem.cpp b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp index 02845fdfe..0fbeefa1e 100644 --- a/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp +++ b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp @@ -500,7 +500,7 @@ namespace ams::fs { R_UNLESS((mode & fs::OpenMode_All) == fs::OpenMode_Read, fs::ResultInvalidOpenMode()); - RomFileTable::FileInfo file_info{}; + RomFileTable::FileInfo file_info; R_TRY(this->GetFileInfo(std::addressof(file_info), path.GetString())); auto file = std::make_unique(this, m_entry_size + file_info.offset.Get(), m_entry_size + file_info.offset.Get() + file_info.size.Get()); diff --git a/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp b/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp index d488fdc93..fc867aeb6 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.m_ptr; - m_value = rhs.m_value; + m_ptr = rhs.ptr; + m_value = rhs.value; rhs.Reset(); } ALWAYS_INLINE ScopedSetter &operator=(ScopedSetter &&rhs) { - m_ptr = rhs.m_ptr; - m_value = rhs.m_value; + m_ptr = rhs.ptr; + m_value = rhs.value; rhs.Reset(); return *this; } diff --git a/libraries/libstratosphere/source/fs/fs_sd_card.cpp b/libraries/libstratosphere/source/fs/fs_sd_card.cpp index cf923c3fd..a1e5964ef 100644 --- a/libraries/libstratosphere/source/fs/fs_sd_card.cpp +++ b/libraries/libstratosphere/source/fs/fs_sd_card.cpp @@ -124,90 +124,4 @@ namespace ams::fs { return inserted; } - Result GetSdCardSpeedMode(SdCardSpeedMode *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the speed mode. */ - s64 speed_mode = 0; - AMS_FS_R_TRY(device_operator->GetSdCardSpeedMode(std::addressof(speed_mode))); - - *out = static_cast(speed_mode); - R_SUCCEED(); - } - - Result GetSdCardCid(void *dst, size_t size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the cid. */ - AMS_FS_R_TRY(device_operator->GetSdCardCid(sf::OutBuffer(dst, size), static_cast(size))); - - R_SUCCEED(); - } - - Result GetSdCardUserAreaSize(s64 *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the size. */ - AMS_FS_R_TRY(device_operator->GetSdCardUserAreaSize(out)); - - R_SUCCEED(); - } - - Result GetSdCardProtectedAreaSize(s64 *out) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the size. */ - AMS_FS_R_TRY(device_operator->GetSdCardProtectedAreaSize(out)); - - R_SUCCEED(); - } - - Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { - /* Check pre-conditions. */ - AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); - AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); - AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); - - auto fsp = impl::GetFileSystemProxyServiceObject(); - - /* Open a device operator. */ - sf::SharedPointer device_operator; - AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); - - /* Get the error info. */ - s64 log_size = 0; - AMS_FS_R_TRY(device_operator->GetAndClearSdCardErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); - - *out_log_size = static_cast(log_size); - R_SUCCEED(); - } - } 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 15dc8c246..c1e99b108 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_20_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_16_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -39,11 +39,7 @@ namespace ams::fs::impl { case KeyGeneration_13_0_0: return "13.0.0-13.2.1"; case KeyGeneration_14_0_0: return "14.0.0-14.1.2"; 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-18.1.0"; - case KeyGeneration_19_0_0: return "19.0.0-19.0.1"; - case KeyGeneration_20_0_0: return "20.0.0-"; + case KeyGeneration_16_0_0: return "16.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp index d3f656c20..c6e674660 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp +++ b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp @@ -33,48 +33,6 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorIsSdCardInserted(std::addressof(m_operator), out.GetPointer())); } - Result GetSdCardSpeedMode(ams::sf::Out out) { - R_RETURN(fsDeviceOperatorGetSdCardSpeedMode(std::addressof(m_operator), out.GetPointer())); - } - - Result GetSdCardCid(ams::sf::OutBuffer out, s64 size) { - R_RETURN(fsDeviceOperatorGetSdCardCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); - } - - Result GetSdCardUserAreaSize(ams::sf::Out out) { - R_RETURN(fsDeviceOperatorGetSdCardUserAreaSize(std::addressof(m_operator), out.GetPointer())); - } - - Result GetSdCardProtectedAreaSize(ams::sf::Out out) { - R_RETURN(fsDeviceOperatorGetSdCardProtectedAreaSize(std::addressof(m_operator), out.GetPointer())); - } - - Result GetAndClearSdCardErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { - static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); - R_RETURN(fsDeviceOperatorGetAndClearSdCardErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); - } - - Result GetMmcCid(ams::sf::OutBuffer out, s64 size) { - R_RETURN(fsDeviceOperatorGetMmcCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); - } - - Result GetMmcSpeedMode(ams::sf::Out out) { - R_RETURN(fsDeviceOperatorGetMmcSpeedMode(std::addressof(m_operator), out.GetPointer())); - } - - Result GetMmcPatrolCount(ams::sf::Out out) { - R_RETURN(fsDeviceOperatorGetMmcPatrolCount(std::addressof(m_operator), out.GetPointer())); - } - - Result GetAndClearMmcErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { - static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); - R_RETURN(fsDeviceOperatorGetAndClearMmcErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); - } - - Result GetMmcExtendedCsd(ams::sf::OutBuffer out, s64 size) { - R_RETURN(fsDeviceOperatorGetMmcExtendedCsd(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); - } - Result IsGameCardInserted(ams::sf::Out out) { R_RETURN(fsDeviceOperatorIsGameCardInserted(std::addressof(m_operator), out.GetPointer())); } @@ -83,19 +41,6 @@ namespace ams::fs::impl { static_assert(sizeof(::FsGameCardHandle) == sizeof(u32)); R_RETURN(fsDeviceOperatorGetGameCardHandle(std::addressof(m_operator), reinterpret_cast<::FsGameCardHandle *>(out.GetPointer()))); } - - Result GetGameCardIdSet(ams::sf::OutBuffer out, s64 size) { - R_RETURN(fsDeviceOperatorGetGameCardIdSet(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); - } - - Result GetGameCardErrorReportInfo(ams::sf::Out out) { - static_assert(sizeof(::FsGameCardErrorReportInfo) == sizeof(fs::GameCardErrorReportInfo)); - R_RETURN(fsDeviceOperatorGetGameCardErrorReportInfo(std::addressof(m_operator), reinterpret_cast<::FsGameCardErrorReportInfo *>(out.GetPointer()))); - } - - Result GetGameCardDeviceId(ams::sf::OutBuffer out, s64 size) { - R_RETURN(fsDeviceOperatorGetGameCardDeviceId(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); - } }; static_assert(fssrv::sf::IsIDeviceOperator); #endif 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 a22a2d888..75b7b7276 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -307,10 +307,6 @@ namespace ams::fssrv { AMS_ABORT("TODO"); } - Result FileSystemProxyImpl::GetProgramId(ams::sf::Out out_program_id, const fssrv::sf::FspPath &path, fs::ContentAttributes attr) { - AMS_ABORT("TODO"); - } - Result FileSystemProxyImpl::GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path) { AMS_ABORT("TODO"); } @@ -373,10 +369,6 @@ namespace ams::fssrv { /* ... */ - Result FileSystemProxyImpl::GetAndClearErrorInfo(ams::sf::Out out) { - AMS_ABORT("TODO"); - } - Result FileSystemProxyImpl::RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count) { AMS_ABORT("TODO"); } @@ -417,10 +409,6 @@ namespace ams::fssrv { AMS_ABORT("TODO"); } - Result FileSystemProxyImpl::GetAndClearMemoryReportInfo(ams::sf::Out out) { - AMS_ABORT("TODO"); - } - /* ... */ Result FileSystemProxyImpl::GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count) { @@ -477,21 +465,11 @@ namespace ams::fssrv { AMS_UNUSED(out_fs, out_verif, path, program_id); } - Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out 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::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/fssrv/fssrv_program_registry_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp index 5de1482f1..2029ce740 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp @@ -34,8 +34,8 @@ namespace ams::fssrv { void ProgramRegistryImpl::Initialize(ProgramRegistryServiceImpl *service) { /* Check pre-conditions. */ - AMS_ASSERT(service != nullptr); - AMS_ASSERT(g_impl == nullptr); + AMS_ASSERT(g_impl != nullptr); + AMS_ASSERT(g_impl == nullptr); /* Set the global service. */ g_impl = service; diff --git a/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp b/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp index 18b157a4a..7fe1ca96a 100644 --- a/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp +++ b/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp @@ -20,7 +20,7 @@ namespace ams::fssrv::impl { namespace { - alignas(0x10) constinit std::byte g_static_buffer_for_program_info_for_initial_process[0x80] = {}; + constinit std::aligned_storage<0x80>::type g_static_buffer_for_program_info_for_initial_process = {}; template class StaticAllocatorForProgramInfoForInitialProcess : public std::allocator { diff --git a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp index 23e4d0b3b..4575a0df4 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp @@ -22,11 +22,9 @@ namespace ams::fssystem { constexpr inline const size_t KeySize = crypto::AesDecryptor128::KeySize; - constexpr inline const size_t NxAcidSignatureKeyGenerationMax = 1; + constexpr inline const size_t AcidSignatureKeyGenerationMax = 1; - constexpr inline const size_t NxAcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize; - - constexpr inline const u8 NxAcidSignatureKeyModulusDev[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = { + constexpr inline const u8 AcidSignatureKeyModulusDev[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = { { 0xD6, 0x34, 0xA5, 0x78, 0x6C, 0x68, 0xCE, 0x5A, 0xC2, 0x37, 0x17, 0xF3, 0x82, 0x45, 0xC6, 0x89, 0xE1, 0x2D, 0x06, 0x67, 0xBF, 0xB4, 0x06, 0x19, 0x55, 0x6B, 0x27, 0x66, 0x0C, 0xA4, 0xB5, 0x87, @@ -65,7 +63,7 @@ namespace ams::fssystem { } }; - constexpr inline const u8 NxAcidSignatureKeyModulusProd[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = { + constexpr inline const u8 AcidSignatureKeyModulusProd[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = { { 0xDD, 0xC8, 0xDD, 0xF2, 0x4E, 0x6D, 0xF0, 0xCA, 0x9E, 0xC7, 0x5D, 0xC7, 0x7B, 0xAD, 0xFE, 0x7D, 0x23, 0x89, 0x69, 0xB6, 0xF2, 0x06, 0xA2, 0x02, 0x88, 0xE1, 0x55, 0x91, 0xAB, 0xCB, 0x4D, 0x50, @@ -104,7 +102,7 @@ namespace ams::fssystem { } }; - static_assert(sizeof(NxAcidSignatureKeyModulusProd) == sizeof(NxAcidSignatureKeyModulusDev)); + static_assert(sizeof(AcidSignatureKeyModulusProd) == sizeof(AcidSignatureKeyModulusDev)); constexpr inline const u8 AcidSignatureKeyPublicExponent[] = { 0x01, 0x00, 0x01 @@ -297,36 +295,10 @@ namespace ams::fssystem { } } - bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation) { - switch (platform) { - case ncm::ContentMetaPlatform::Nx: - return key_generation <= NxAcidSignatureKeyGenerationMax; - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } - - 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 ncm::ContentMetaPlatform::Nx: - { - const size_t used_keygen = (key_generation % (NxAcidSignatureKeyGenerationMax + 1)); - return prod ? NxAcidSignatureKeyModulusProd[used_keygen] : NxAcidSignatureKeyModulusDev[used_keygen]; - } - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } - - size_t GetAcidSignatureKeyModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { - AMS_UNUSED(unk_unused); - - switch (platform) { - case ncm::ContentMetaPlatform::Nx: - return NxAcidSignatureKeyModulusSize; - AMS_UNREACHABLE_DEFAULT_CASE(); - } + const u8 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation) { + AMS_ASSERT(key_generation <= AcidSignatureKeyGenerationMax); + const size_t used_keygen = (key_generation % (AcidSignatureKeyGenerationMax + 1)); + return prod ? AcidSignatureKeyModulusProd[used_keygen] : AcidSignatureKeyModulusDev[used_keygen]; } const u8 *GetAcidSignatureKeyPublicExponent() { diff --git a/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp b/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp index 0f5760e64..2a11b1550 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/htc/server/rpc/htc_rpc_client.cpp b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp index df5f84d5d..19d29b03b 100644 --- a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp +++ b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp @@ -288,7 +288,7 @@ namespace ams::htc::server::rpc { /* Get a task. */ Task *task; u32 task_id{}; - PacketCategory category{}; + PacketCategory category; do { /* Dequeue a task. */ R_TRY(m_task_queue.Take(std::addressof(task_id), std::addressof(category))); diff --git a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp index 318c01645..62637b490 100644 --- a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp +++ b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp @@ -41,7 +41,7 @@ namespace ams::htc::server::rpc { #else static constexpr size_t MaxTaskSize = 0xE1D8; #endif - struct TaskStorage { alignas(alignof(void *)) std::byte _storage[MaxTaskSize]; }; + using TaskStorage = typename std::aligned_storage::type; private: bool m_valid[MaxRpcCount]{}; TaskStorage m_storages[MaxRpcCount]{}; diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp index aac4c7195..1900c90cf 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp @@ -39,7 +39,7 @@ namespace ams::htcs::impl { void HtcsManager::Socket(s32 *out_err, s32 *out_desc, bool enable_disconnection_emulation) { /* Invoke our implementation. */ - s32 err = -1, desc = -1; + s32 err, desc; const Result result = m_impl->CreateSocket(std::addressof(err), std::addressof(desc), enable_disconnection_emulation); /* Set output. */ @@ -71,7 +71,7 @@ namespace ams::htcs::impl { void HtcsManager::Connect(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; + s32 err; const Result result = m_impl->Connect(std::addressof(err), desc, address); /* Set output. */ @@ -90,7 +90,7 @@ namespace ams::htcs::impl { void HtcsManager::Bind(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; + s32 err; const Result result = m_impl->Bind(std::addressof(err), desc, address); /* Set output. */ @@ -109,7 +109,7 @@ namespace ams::htcs::impl { void HtcsManager::Listen(s32 *out_err, s32 *out_res, s32 backlog_count, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; + s32 err; const Result result = m_impl->Listen(std::addressof(err), desc, backlog_count); /* Set output. */ @@ -128,8 +128,8 @@ namespace ams::htcs::impl { void HtcsManager::Recv(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 flags, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 recv_size = -1; + s32 err; + s64 recv_size; const Result result = m_impl->Receive(std::addressof(err), std::addressof(recv_size), buffer, size, desc, flags); /* Set output. */ @@ -148,8 +148,8 @@ namespace ams::htcs::impl { void HtcsManager::Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 flags, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 send_size = -1; + s32 err; + s64 send_size; const Result result = m_impl->Send(std::addressof(err), std::addressof(send_size), buffer, size, desc, flags); /* Set output. */ @@ -168,7 +168,7 @@ namespace ams::htcs::impl { void HtcsManager::Shutdown(s32 *out_err, s32 *out_res, s32 how, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; + s32 err; const Result result = m_impl->Shutdown(std::addressof(err), desc, how); /* Set output. */ @@ -191,7 +191,7 @@ namespace ams::htcs::impl { void HtcsManager::Fcntl(s32 *out_err, s32 *out_res, s32 command, s32 value, s32 desc) { /* Invoke our implementation. */ - s32 err = -1, res = -1; + s32 err, res; const Result result = m_impl->Fcntl(std::addressof(err), std::addressof(res), desc, command, value); /* Set output. */ @@ -210,7 +210,7 @@ namespace ams::htcs::impl { void HtcsManager::AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; + s32 err; const Result result = m_impl->AcceptResults(std::addressof(err), out_desc, out_address, task_id, desc); /* Set output. */ @@ -233,8 +233,8 @@ namespace ams::htcs::impl { void HtcsManager::RecvResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 size = -1; + s32 err; + s64 size; const Result result = m_impl->RecvResults(std::addressof(err), std::addressof(size), buffer, buffer_size, task_id, desc); /* Set output. */ @@ -265,8 +265,8 @@ namespace ams::htcs::impl { void HtcsManager::SendResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 size = -1; + s32 err; + s64 size; const Result result = m_impl->SendResults(std::addressof(err), std::addressof(size), task_id, desc); /* Set output. */ @@ -293,7 +293,7 @@ namespace ams::htcs::impl { Result HtcsManager::ContinueSend(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s64 size = -1; + s64 size; R_TRY_CATCH(m_impl->ContinueSend(std::addressof(size), buffer, buffer_size, task_id, desc)) { R_CONVERT(htclow::ResultInvalidChannelState, tma::ResultUnknown()) R_CONVERT(htc::ResultTaskCancelled, tma::ResultUnknown()) @@ -306,8 +306,8 @@ namespace ams::htcs::impl { void HtcsManager::EndSend(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 size = -1; + s32 err; + s64 size; const Result result = m_impl->EndSend(std::addressof(err), std::addressof(size), task_id, desc); /* Set output. */ @@ -334,8 +334,8 @@ namespace ams::htcs::impl { void HtcsManager::EndRecv(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err = -1; - s64 size = -1; + s32 err; + s64 size; const Result result = m_impl->EndRecv(std::addressof(err), std::addressof(size), buffer, buffer_size, task_id, desc); /* Set output. */ @@ -367,8 +367,8 @@ namespace ams::htcs::impl { Result HtcsManager::EndSelect(s32 *out_err, s32 *out_count, Span read_handles, Span write_handles, Span exception_handles, u32 task_id) { /* Invoke our implementation. */ - s32 err = -1; - bool empty = false; + s32 err; + bool empty; const Result result = m_impl->EndSelect(std::addressof(err), std::addressof(empty), read_handles, write_handles, exception_handles, task_id); /* Set output. */ diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c index 3a0dca194..7d0b4f907 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c +++ b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c @@ -32,14 +32,8 @@ 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, 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, +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) { + return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *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 b52807112..30a5e4163 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, const LoaderProgramAttributes *attr); +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc); 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 f461f9f7f..8441977f5 100644 --- a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp +++ b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp @@ -19,14 +19,12 @@ namespace ams::ldr::pm { /* Information API. */ - 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 CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) { + R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, 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 GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) { + R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(out))); } Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) { @@ -42,10 +40,9 @@ namespace ams::ldr::pm { R_RETURN(ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast(program_id))); } - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) { + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); - 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)))); + R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)))); } Result SetEnabledProgramVerification(bool enabled) { diff --git a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp index dded90f31..655a2cba1 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp @@ -785,30 +785,25 @@ namespace ams::ncm { Result ContentManagerImpl::BuildContentMetaDatabase(StorageId storage_id) { if (hos::GetVersion() < hos::Version_5_0_0) { - /* On < 5.0.0, perform an actual build of the database. */ - R_RETURN(this->BuildContentMetaDatabaseImpl(storage_id)); + /* Temporarily activate the database. */ + R_TRY(this->ActivateContentMetaDatabase(storage_id)); + ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; + + /* Open the content meta database and storage. */ + ContentMetaDatabase meta_db; + ContentStorage storage; + R_TRY(ncm::OpenContentMetaDatabase(std::addressof(meta_db), storage_id)); + R_TRY(ncm::OpenContentStorage(std::addressof(storage), storage_id)); + + /* Create a builder, and build. */ + ContentMetaDatabaseBuilder builder(std::addressof(meta_db)); + R_RETURN(builder.BuildFromStorage(std::addressof(storage))); } else { /* On 5.0.0+, building just performs an import. */ R_RETURN(this->ImportContentMetaDatabase(storage_id, false)); } } - Result ContentManagerImpl::BuildContentMetaDatabaseImpl(StorageId storage_id) { - /* Temporarily activate the database. */ - R_TRY(this->ActivateContentMetaDatabase(storage_id)); - ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; - - /* Open the content meta database and storage. */ - ContentMetaDatabase meta_db; - ContentStorage storage; - R_TRY(ncm::OpenContentMetaDatabase(std::addressof(meta_db), storage_id)); - R_TRY(ncm::OpenContentStorage(std::addressof(storage), storage_id)); - - /* Create a builder, and build. */ - ContentMetaDatabaseBuilder builder(std::addressof(meta_db)); - R_RETURN(builder.BuildFromStorage(std::addressof(storage))); - } - Result ContentManagerImpl::ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition) { /* Only support importing BuiltInSystem. */ AMS_ABORT_UNLESS(storage_id == StorageId::BuiltInSystem); @@ -836,31 +831,6 @@ namespace ams::ncm { R_SUCCEED(); } - bool ContentManagerImpl::IsNeedRebuildSystemContentMetaDatabase() { - /* TODO: Should hos::GetVersion() >= hos::Version_17_0_0 be checked? */ - - /* If we do not actually have a content meta db, we should re-build. */ - if (R_FAILED(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem))) { - return true; - } - - /* We have a content meta db. Temporarily, activate it. */ - if (R_FAILED(this->ActivateContentMetaDatabase(StorageId::BuiltInSystem))) { - return true; - } - ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(StorageId::BuiltInSystem); }; - - /* Open the content meta db. */ - ContentMetaDatabase meta_db; - R_ABORT_UNLESS(ncm::OpenContentMetaDatabase(std::addressof(meta_db), StorageId::BuiltInSystem)); - - /* List the meta db's contents. */ - const auto list_count = meta_db.ListContentMeta(nullptr, 0); - - /* We need to rebuild if the db has zero entries. */ - return list_count.total == 0; - } - Result ContentManagerImpl::Initialize(const ContentManagerConfig &config) { /* Initialize based on whether integrated content is enabled. */ if (config.IsIntegratedSystemContentEnabled()) { @@ -971,20 +941,6 @@ namespace ams::ncm { } R_TRY(this->ActivateContentStorage(StorageId::BuiltInSystem)); - /* NOTE: This logic is unofficial. */ - /* Beginning with 17.0.0+, save management behavior changed. The primary symptom of this is either verify fail */ - /* or an empty kvs, both of which we can fix by performing a rebuild. */ - if (this->IsNeedRebuildSystemContentMetaDatabase()) { - /* Clean up the system content meta database, to ensure creation can succeed. */ - this->CleanupContentMetaDatabase(StorageId::BuiltInSystem); - - /* Create the content meta database. */ - R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); - - /* Rebuild the content meta database. */ - R_TRY(this->BuildContentMetaDatabaseImpl(StorageId::BuiltInSystem)); - } - /* Setup the content meta database for system. */ if (R_FAILED(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem))) { R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp index 02f648a50..c505ecbd8 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp @@ -26,7 +26,6 @@ namespace ams::ncm { .content_count = src.content_count, .content_meta_count = src.content_meta_count, .attributes = src.attributes, - .platform = src.platform, }; } @@ -43,7 +42,6 @@ namespace ams::ncm { .content_count = src.content_count, .content_meta_count = src.content_meta_count, .attributes = src.attributes, - .platform = src.platform, }; } 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 4cf5175b2..8b84f9114 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp @@ -518,50 +518,4 @@ namespace ams::ncm { R_RETURN(this->GetContentInfoImpl(out_content_info.GetPointer(), key, type, util::make_optional(id_offset))); } - Result ContentMetaDatabaseImpl::GetPlatform(sf::Out out, const ContentMetaKey &key) { - R_TRY(this->EnsureEnabled()); - - /* Obtain the content meta for the key. */ - const void *meta; - size_t meta_size; - R_TRY(this->GetContentMetaPointer(&meta, &meta_size, key)); - - /* Create a reader. */ - ContentMetaReader reader(meta, meta_size); - - /* Set the ouput value. */ - out.SetValue(reader.GetHeader()->platform); - 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 b4e3803d7..7b51783cc 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp @@ -64,8 +64,6 @@ namespace ams::ncm { virtual Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key) override; 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 59d6130e9..d89483d80 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 @@ -80,8 +80,6 @@ namespace ams::ncm { virtual Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key) = 0; 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_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp index db0387503..0a8359d93 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp @@ -918,19 +918,4 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } - Result ContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { - R_TRY(this->EnsureEnabled()); - - /* Get the path of the content. */ - Path path; - R_TRY(this->GetPath(std::addressof(path), content_id)); - - /* Obtain the program id for the content. */ - ncm::ProgramId program_id; - R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); - - out.SetValue(program_id); - R_SUCCEED(); - } - } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp index 5f9ae6904..b9b9b7455 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp @@ -105,7 +105,6 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override; virtual Result RegisterPath(const ContentId &content_id, const Path &path) override; virtual Result ClearRegisteredPath() override; - virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp index 945d41683..52f21022b 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp @@ -79,7 +79,6 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) = 0; virtual Result RegisterPath(const ContentId &content_id, const Path &path) = 0; virtual Result ClearRegisteredPath() = 0; - virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) = 0; /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } diff --git a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp index 592a2df3f..3ae075e09 100644 --- a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp @@ -224,27 +224,4 @@ namespace ams::ncm { R_SUCCEED(); } - Result HostContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { - R_TRY(this->EnsureEnabled()); - - /* Get the content path. */ - Path path; - R_TRY(m_registered_content->GetPath(std::addressof(path), content_id)); - - /* Check for correct extension. */ - const auto path_len = std::strlen(path.str); - const char *extension = path.str + path_len - 1; - if (*extension == '/') { - --extension; - } - R_UNLESS(path_len >= 4 && std::memcmp(extension - 4, ".ncd", 4) == 0, ncm::ResultInvalidContentMetaDirectory()); - - /* Obtain the program id for the content. */ - ncm::ProgramId program_id; - R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); - - out.SetValue(program_id); - R_SUCCEED(); - } - } diff --git a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp index 4a54063b3..7b4472c74 100644 --- a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp @@ -77,7 +77,6 @@ namespace ams::ncm { Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr); Result RegisterPath(const ContentId &content_id, const Path &path); Result ClearRegisteredPath(); - Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr); /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } 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 148471e86..2a0ca8f51 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 @@ -446,45 +446,4 @@ namespace ams::ncm { })); } - Result IntegratedContentMetaDatabaseImpl::GetPlatform(sf::Out out, const ContentMetaKey &key) { - /* Lock ourselves. */ - std::scoped_lock lk(m_mutex); - - /* Check that we're enabled. */ - R_TRY(this->EnsureEnabled()); - - /* Check that our list has interfaces to check. */ - R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentMetaNotFound()); - - /* Check each interface in turn. */ - R_RETURN(m_list.TryEach([&](const auto &data) { - /* Try the current interface. */ - R_RETURN(data.interface->GetPlatform(out, key)); - })); - } - - 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_integrated_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp index 1853e6b89..6c7436f44 100644 --- a/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp @@ -326,31 +326,4 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } - Result IntegratedContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { - /* Lock ourselves. */ - std::scoped_lock lk(m_mutex); - - /* Check that we're enabled. */ - R_TRY(this->EnsureEnabled()); - - /* Check that our list has interfaces to check. */ - R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentNotFound()); - - /* Check each interface in turn. */ - R_TRY(m_list.TryEach([&](const auto &data) { - /* Check if the current interface has it. */ - bool has; - R_TRY(data.interface->Has(std::addressof(has), content_id)); - - /* If it doesn't, continue on. */ - R_UNLESS(has, ncm::ResultContentNotFound()); - - - /* If it does, read the file. */ - R_RETURN(data.interface->GetProgramId(out, content_id, attr)); - })); - - R_SUCCEED(); - } - } diff --git a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp index a25f23b1d..635730585 100644 --- a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp @@ -297,19 +297,4 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } - Result ReadOnlyContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { - R_TRY(this->EnsureEnabled()); - - /* Get the path of the content. */ - Path path; - R_TRY(this->GetPath(std::addressof(path), content_id)); - - /* Obtain the program id for the content. */ - ncm::ProgramId program_id; - R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); - - out.SetValue(program_id); - R_SUCCEED(); - } - } diff --git a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp index c00a3ae11..f42c630da 100644 --- a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp @@ -58,7 +58,6 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override; virtual Result RegisterPath(const ContentId &content_id, const Path &path) override; virtual Result ClearRegisteredPath() override; - virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) override; }; } 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 abba78c73..0919d6d45 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 @@ -186,17 +186,6 @@ namespace ams::ncm { AMS_UNUSED(out_content_info, key, type, id_offset); AMS_ABORT(); } - - Result GetPlatform(sf::Out out, const ContentMetaKey &key) { - 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/ncm/ncm_remote_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp index 87c88bbdc..ac809a5e6 100644 --- a/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp @@ -219,11 +219,6 @@ namespace ams::ncm { R_RETURN(ncmContentStorageClearRegisteredPath(std::addressof(m_srv))); } - Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { - static_assert(sizeof(ncm::ProgramId) == sizeof(u64)); - R_RETURN(ncmContentStorageGetProgramId(std::addressof(m_srv), reinterpret_cast(out.GetPointer()), Convert(content_id), Convert(attr))); - } - /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } Result Register_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id) { R_RETURN(this->Register(placeholder_id, content_id)); } diff --git a/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp index 27ffab700..fd8e78f9f 100644 --- a/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp @@ -23,7 +23,7 @@ namespace ams::os::impl { /* Map at a random address. */ R_RETURN(impl::GetAslrSpaceManager().MapAtRandomAddress(out_address, [](uintptr_t map_address, size_t map_size) -> Result { - R_TRY_CATCH(svc::MapInsecurePhysicalMemory(map_address, map_size)) { + R_TRY_CATCH(svc::MapInsecureMemory(map_address, map_size)) { R_CONVERT(svc::ResultOutOfMemory, os::ResultOutOfMemory()) R_CONVERT(svc::ResultInvalidCurrentMemory, os::ResultInvalidCurrentMemoryState()) } R_END_TRY_CATCH_WITH_ABORT_UNLESS; @@ -39,7 +39,7 @@ namespace ams::os::impl { } void InsecureMemoryImpl::FreeInsecureMemoryImpl(uintptr_t address, size_t size) { - R_ABORT_UNLESS(svc::UnmapInsecurePhysicalMemory(address, size)); + R_ABORT_UNLESS(svc::UnmapInsecureMemory(address, size)); } } 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 686cc6995..de7b241a6 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,7 +27,6 @@ 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 94450ef26..b336576f1 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,7 +43,6 @@ 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/os/impl/os_vamm_manager_impl.os.horizon.hpp b/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp index fb1519f88..dad8aee6f 100644 --- a/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp +++ b/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp @@ -21,12 +21,11 @@ namespace ams::os::impl { class VammManagerHorizonImpl { public: static void GetReservedRegionImpl(uintptr_t *out_start, uintptr_t *out_size) { - u64 start, size, extra_size; - R_ABORT_UNLESS(svc::GetInfo(std::addressof(start), svc::InfoType_AliasRegionAddress, svc::PseudoHandle::CurrentProcess, 0)); - R_ABORT_UNLESS(svc::GetInfo(std::addressof(size), svc::InfoType_AliasRegionSize, svc::PseudoHandle::CurrentProcess, 0)); - R_ABORT_UNLESS(svc::GetInfo(std::addressof(extra_size), svc::InfoType_AliasRegionExtraSize, svc::PseudoHandle::CurrentProcess, 0)); + u64 start, size; + R_ABORT_UNLESS(svc::GetInfo(std::addressof(start), svc::InfoType_AliasRegionAddress, svc::PseudoHandle::CurrentProcess, 0)); + R_ABORT_UNLESS(svc::GetInfo(std::addressof(size), svc::InfoType_AliasRegionSize, svc::PseudoHandle::CurrentProcess, 0)); *out_start = start; - *out_size = size - extra_size; + *out_size = size; } static Result AllocatePhysicalMemoryImpl(uintptr_t address, size_t size) { diff --git a/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp b/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp index a579ff449..5f947f255 100644 --- a/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp +++ b/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp @@ -19,13 +19,9 @@ namespace ams::osdbg::impl { template - struct AlignedStorageIlp32 { - alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u32)]; - }; + using AlignedStorageIlp32 = typename std::aligned_storage::type; template - struct AlignedStorageLp64 { - alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u64)]; - }; + using AlignedStorageLp64 = typename std::aligned_storage::type; } diff --git a/libraries/libstratosphere/source/patcher/patcher_api.cpp b/libraries/libstratosphere/source/patcher/patcher_api.cpp index 5d493b3ec..f74259bd0 100644 --- a/libraries/libstratosphere/source/patcher/patcher_api.cpp +++ b/libraries/libstratosphere/source/patcher/patcher_api.cpp @@ -167,7 +167,6 @@ namespace ams::patcher { /* Apply patch. */ if (patch_offset + rle_size > mapped_size) { - AMS_ABORT_UNLESS(patch_offset <= mapped_size); rle_size = mapped_size - patch_offset; } std::memset(mapped_module + patch_offset, buffer[0], rle_size); @@ -191,7 +190,6 @@ namespace ams::patcher { /* Apply patch. */ u32 read_size = patch_size; if (patch_offset + read_size > mapped_size) { - AMS_ABORT_UNLESS(patch_offset <= mapped_size); read_size = mapped_size - patch_offset; } { diff --git a/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp b/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp index 559e21475..2eed37653 100644 --- a/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp +++ b/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp @@ -44,13 +44,6 @@ namespace ams::pm::dmnt { R_SUCCEED(); } - Result HookToCreateProcess(os::NativeHandle *out_handle, const ncm::ProgramId program_id) { - Event evt; - R_TRY(pmdmntHookToCreateProcess(std::addressof(evt), static_cast(program_id))); - *out_handle = evt.revent; - R_SUCCEED(); - } - Result AtmosphereGetProcessInfo(os::NativeHandle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { *out_handle = os::InvalidNativeHandle; *out_loc = {}; diff --git a/libraries/libstratosphere/source/pm/pm_info_api.cpp b/libraries/libstratosphere/source/pm/pm_info_api.cpp index 9fdf4a865..182c09c8a 100644 --- a/libraries/libstratosphere/source/pm/pm_info_api.cpp +++ b/libraries/libstratosphere/source/pm/pm_info_api.cpp @@ -28,13 +28,13 @@ namespace ams::pm::info { R_RETURN(pminfoAtmosphereGetProcessId(reinterpret_cast(out_process_id), static_cast(program_id))); } - Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out) { - static_assert(sizeof(pm::ResourceLimitValue) == sizeof(::PmResourceLimitValues)); + Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out) { + static_assert(sizeof(pm::ResourceLimitValues) == sizeof(::PmResourceLimitValues)); R_RETURN(pminfoGetAppletCurrentResourceLimitValues(reinterpret_cast(out))); } - Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out) { - static_assert(sizeof(pm::ResourceLimitValue) == sizeof(::PmResourceLimitValues)); + Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out) { + static_assert(sizeof(pm::ResourceLimitValues) == sizeof(::PmResourceLimitValues)); R_RETURN(pminfoGetAppletPeakResourceLimitValues(reinterpret_cast(out))); } diff --git a/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp b/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp index 539ceb04f..09ec1a8a5 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 b408bf845..51f3b6409 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 a67ae4800..b4d959b24 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::InvalidNativeHandle; + os::NativeHandle query_handle; R_TRY(sm::mitm::InstallMitm(out_port_handle, std::addressof(query_handle), service_name)); /* Register the query handle. */ diff --git a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp index c5c450b1b..acec07407 100644 --- a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp +++ b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp @@ -893,10 +893,6 @@ namespace ams::spl::impl { R_RETURN(PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, smc::EsDeviceUniqueKeyType::ArchiveKey, generation)); } - Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) { - R_RETURN(PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, smc::EsDeviceUniqueKeyType::Unknown2, generation)); - } - /* FS */ Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) { R_RETURN(DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option)); diff --git a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp index 966912ad9..fead3970e 100644 --- a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp +++ b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp @@ -50,7 +50,6 @@ namespace ams::spl::smc { enum EsCommonKeyType { EsCommonKeyType_TitleKey = 0, EsCommonKeyType_ArchiveKey = 1, - EsCommonKeyType_Unknown2 = 2, EsCommonKeyType_Count, }; @@ -87,7 +86,6 @@ namespace ams::spl::smc { constexpr const u8 EsCommonKeySources[EsCommonKeyType_Count][AesKeySize] = { [EsCommonKeyType_TitleKey] = { 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B }, [EsCommonKeyType_ArchiveKey] = { 0x3B, 0x78, 0xF2, 0x61, 0x0F, 0x9D, 0x5A, 0xE2, 0x7B, 0x4E, 0x45, 0xAF, 0xCB, 0x0B, 0x67, 0x4D }, - [EsCommonKeyType_Unknown2] = { 0x42, 0x64, 0x0B, 0xE3, 0x5F, 0xC6, 0xBE, 0x47, 0xC7, 0xB4, 0x84, 0xC5, 0xEB, 0x63, 0xAA, 0x02 }, }; constexpr u64 InvalidAsyncKey = 0; diff --git a/libraries/libvapours/include/vapours/allocator.hpp b/libraries/libvapours/include/vapours/allocator.hpp index 3828d4a05..b5d294bfe 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)*/ 0x8; + constexpr inline size_t DefaultAlignment = alignof(max_align_t); 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 517ce8198..3d84418e0 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 9 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 3 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 5 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 5 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 3 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 16 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 #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 643ee7f6f..9e6357e22 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -78,22 +78,8 @@ #define ATMOSPHERE_TARGET_FIRMWARE_16_0_2 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 2) #define ATMOSPHERE_TARGET_FIRMWARE_16_0_3 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 3) #define ATMOSPHERE_TARGET_FIRMWARE_16_1_0 ATMOSPHERE_TARGET_FIRMWARE(16, 1, 0) -#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_20_1_0 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_20_1_1 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 1) -#define ATMOSPHERE_TARGET_FIRMWARE_20_1_5 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 5) -#define ATMOSPHERE_TARGET_FIRMWARE_20_2_0 ATMOSPHERE_TARGET_FIRMWARE(20, 2, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_20_3_0 ATMOSPHERE_TARGET_FIRMWARE(20, 3, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_3_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_1_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -164,20 +150,6 @@ namespace ams { TargetFirmware_16_0_2 = ATMOSPHERE_TARGET_FIRMWARE_16_0_2, TargetFirmware_16_0_3 = ATMOSPHERE_TARGET_FIRMWARE_16_0_3, TargetFirmware_16_1_0 = ATMOSPHERE_TARGET_FIRMWARE_16_1_0, - 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_20_1_0 = ATMOSPHERE_TARGET_FIRMWARE_20_1_0, - TargetFirmware_20_1_1 = ATMOSPHERE_TARGET_FIRMWARE_20_1_1, - TargetFirmware_20_1_5 = ATMOSPHERE_TARGET_FIRMWARE_20_1_5, - TargetFirmware_20_2_0 = ATMOSPHERE_TARGET_FIRMWARE_20_2_0, - TargetFirmware_20_3_0 = ATMOSPHERE_TARGET_FIRMWARE_20_3_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, diff --git a/libraries/libvapours/include/vapours/crypto.hpp b/libraries/libvapours/include/vapours/crypto.hpp index 205bbb7e6..63cfcb2e4 100644 --- a/libraries/libvapours/include/vapours/crypto.hpp +++ b/libraries/libvapours/include/vapours/crypto.hpp @@ -30,7 +30,6 @@ #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 deleted file mode 100644 index c252263e1..000000000 --- a/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp +++ /dev/null @@ -1,61 +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 . - */ - -#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 deleted file mode 100644 index 052dab42e..000000000 --- a/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp +++ /dev/null @@ -1,51 +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 . - */ - -#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 deleted file mode 100644 index fb237540d..000000000 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp +++ /dev/null @@ -1,128 +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 . - */ - -#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/capsrv_results.hpp b/libraries/libvapours/include/vapours/results/capsrv_results.hpp index f1b36c3b9..d353ab93f 100644 --- a/libraries/libvapours/include/vapours/results/capsrv_results.hpp +++ b/libraries/libvapours/include/vapours/results/capsrv_results.hpp @@ -54,7 +54,6 @@ namespace ams::capsrv { R_DEFINE_ERROR_RANGE(InternalError, 1024, 2047); R_DEFINE_ERROR_RESULT(InternalJpegEncoderError, 1210); - R_DEFINE_ERROR_RESULT(InternalJpegOutBufferShortage, 1211); R_DEFINE_ERROR_RESULT(InternalJpegWorkMemoryShortage, 1212); R_DEFINE_ERROR_RANGE(InternalFileDataVerificationError, 1300, 1399); diff --git a/libraries/libvapours/include/vapours/results/loader_results.hpp b/libraries/libvapours/include/vapours/results/loader_results.hpp index 25e3debee..825be3784 100644 --- a/libraries/libvapours/include/vapours/results/loader_results.hpp +++ b/libraries/libvapours/include/vapours/results/loader_results.hpp @@ -21,20 +21,18 @@ 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(InvalidProgramAttributes, 14); + 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(OutOfAddressSpace, 51); R_DEFINE_ERROR_RESULT(InvalidNroImage, 52); diff --git a/libraries/libvapours/include/vapours/results/ncm_results.hpp b/libraries/libvapours/include/vapours/results/ncm_results.hpp index 2092cf0ce..45d7c3a0a 100644 --- a/libraries/libvapours/include/vapours/results/ncm_results.hpp +++ b/libraries/libvapours/include/vapours/results/ncm_results.hpp @@ -54,8 +54,6 @@ namespace ams::ncm { R_DEFINE_ERROR_RESULT(InvalidContentMetaFileSize, 390); R_DEFINE_ERROR_RESULT(InvalidAddOnContentMetaExtendedHeader, 400); - R_DEFINE_ERROR_RESULT(InvalidContentMetaDirectory, 430); - R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258); R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251); R_DEFINE_ERROR_RESULT(BuiltInSystemContentStorageNotActive, 252); diff --git a/libraries/libvapours/include/vapours/results/pm_results.hpp b/libraries/libvapours/include/vapours/results/pm_results.hpp index 4e4c0e24b..4c9e51ad5 100644 --- a/libraries/libvapours/include/vapours/results/pm_results.hpp +++ b/libraries/libvapours/include/vapours/results/pm_results.hpp @@ -27,6 +27,5 @@ 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/results/results_common.hpp b/libraries/libvapours/include/vapours/results/results_common.hpp index 67d81faad..0d0624eb8 100644 --- a/libraries/libvapours/include/vapours/results/results_common.hpp +++ b/libraries/libvapours/include/vapours/results/results_common.hpp @@ -85,13 +85,14 @@ namespace ams { }; /* Use CRTP for Results. */ + template class ResultBase { public: using BaseType = typename ResultTraits::BaseType; static constexpr BaseType SuccessValue = ResultTraits::SuccessValue; public: - constexpr ALWAYS_INLINE BaseType GetModule(this auto const &self) { return ResultTraits::GetModuleFromValue(self.GetValue()); } - constexpr ALWAYS_INLINE BaseType GetDescription(this auto const &self) { return ResultTraits::GetDescriptionFromValue(self.GetValue()); } + constexpr ALWAYS_INLINE BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast(this)->GetValue()); } + constexpr ALWAYS_INLINE BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast(this)->GetValue()); } }; class ResultInternalAccessor; @@ -100,10 +101,10 @@ namespace ams { class ResultSuccess; - class Result final : public result::impl::ResultBase { + class Result final : public result::impl::ResultBase { friend class result::impl::ResultInternalAccessor; public: - using Base = typename result::impl::ResultBase; + using Base = typename result::impl::ResultBase; private: typename Base::BaseType m_value; private: @@ -156,9 +157,9 @@ namespace ams { } - class ResultSuccess final : public result::impl::ResultBase { + class ResultSuccess final : public result::impl::ResultBase { public: - using Base = typename result::impl::ResultBase; + using Base = typename result::impl::ResultBase; public: constexpr ALWAYS_INLINE operator Result() const { return result::impl::MakeResult(Base::SuccessValue); } static constexpr ALWAYS_INLINE bool CanAccept(Result result) { return result.IsSuccess(); } @@ -188,9 +189,9 @@ namespace ams { namespace result::impl { template - class ResultErrorBase : public ResultBase { + class ResultErrorBase : public ResultBase> { public: - using Base = typename result::impl::ResultBase; + using Base = typename result::impl::ResultBase>; static constexpr typename Base::BaseType Module = _Module; static constexpr typename Base::BaseType Description = _Description; static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue::value; diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp index e33b88a56..355ac1412 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp @@ -201,7 +201,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("ldr x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory"); } else { - static_assert(false, "Invalid Size"); + static_assert(Size != Size); } } @@ -212,7 +212,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("ldp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory"); } else { - static_assert(false, "Invalid Size"); + static_assert(Size != Size); } } @@ -223,7 +223,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("str x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory"); } else { - static_assert(false, "Invalid Size"); + static_assert(Size != Size); } } @@ -234,7 +234,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("stp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory"); } else { - static_assert(false, "Invalid Size"); + static_assert(Size != Size); } } diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp index ab1ee69f9..213c0d397 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp @@ -461,7 +461,7 @@ namespace ams::svc::codegen::impl { if constexpr (CodeGenKind == CodeGenerationKind::SvcInvocationToKernelProcedure) { return Operation::ImplType::template CanGenerateCodeForSvcInvocationToKernelProcedure(allocator); } else { - static_assert(false, "Invalid CodeGenerationKind"); + static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind"); } } @@ -474,7 +474,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (CodeGenKind == CodeGenerationKind::KernelProcedureToSvcInvocation) { Operation::ImplType::template GenerateCodeForKernelProcedureToSvcInvocation(mcg); } else { - static_assert(false, "Invalid CodeGenerationKind"); + static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind"); } } }; diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp index 7dcb8e734..47dba1d29 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp @@ -127,7 +127,7 @@ namespace ams::svc::codegen::impl { META_CODE_OPERATION_KIND_GENERATE_CODE(Pack) META_CODE_OPERATION_KIND_GENERATE_CODE(Unpack) META_CODE_OPERATION_KIND_GENERATE_CODE(LoadStackAddress) - else { static_assert(false, "Unknown MetaOperationKind"); } + else { static_assert(Kind != Kind, "Unknown MetaOperationKind"); } #undef META_CODE_OPERATION_KIND_GENERATE_CODE } diff --git a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp index 7e4121aa3..d4668e445 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(int64_t, value), INPUT(int64_t, timeout_ns)) \ + 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(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)) \ @@ -99,7 +99,7 @@ HANDLER(0x52, Result, UnmapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ HANDLER(0x53, Result, CreateInterruptEvent, OUTPUT(::ams::svc::Handle, out_read_handle), INPUT(int32_t, interrupt_id), INPUT(::ams::svc::InterruptType, interrupt_type)) \ HANDLER(0x54, Result, QueryPhysicalAddress, OUTPUT(::ams::svc::NAMESPACE::PhysicalMemoryInfo, out_info), INPUT(::ams::svc::Address, address)) \ - HANDLER(0x55, Result, QueryMemoryMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x55, Result, QueryIoMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ HANDLER(0x56, Result, CreateDeviceAddressSpace, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, das_address), INPUT(uint64_t, das_size)) \ HANDLER(0x57, Result, AttachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ HANDLER(0x58, Result, DetachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ @@ -142,8 +142,8 @@ HANDLER(0x7E, Result, SetResourceLimitLimitValue, INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which), INPUT(int64_t, limit_value)) \ HANDLER(0x7F, void, CallSecureMonitor, OUTPUT(::ams::svc::NAMESPACE::SecureMonitorArguments, args)) \ \ - HANDLER(0x90, Result, MapInsecurePhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x91, Result, UnmapInsecurePhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x90, Result, MapInsecureMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x91, Result, UnmapInsecureMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ \ HANDLER(0x2E, Result, LegacyGetFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags), INPUT(int64_t, ns)) \ HANDLER(0x55, Result, LegacyQueryIoMapping, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 21ab685d0..c600519df 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -112,11 +112,10 @@ namespace ams::svc { }; enum MemoryAttribute : u32 { - MemoryAttribute_Locked = (1 << 0), - MemoryAttribute_IpcLocked = (1 << 1), - MemoryAttribute_DeviceShared = (1 << 2), - MemoryAttribute_Uncached = (1 << 3), - MemoryAttribute_PermissionLocked = (1 << 4), + MemoryAttribute_Locked = (1 << 0), + MemoryAttribute_IpcLocked = (1 << 1), + MemoryAttribute_DeviceShared = (1 << 2), + MemoryAttribute_Uncached = (1 << 3), }; enum MemoryMapping : u32 { @@ -190,9 +189,6 @@ namespace ams::svc { InfoType_ThreadTickCount = 25, InfoType_IsSvcPermitted = 26, InfoType_IoRegionHint = 27, - InfoType_AliasRegionExtraSize = 28, - /* ... */ - InfoType_TransferMemoryHint = 34, InfoType_MesosphereMeta = 65000, InfoType_MesosphereCurrentProcess = 65001, @@ -263,7 +259,6 @@ namespace ams::svc { ArbitrationType_WaitIfLessThan = 0, ArbitrationType_DecrementAndWaitIfLessThan = 1, ArbitrationType_WaitIfEqual = 2, - ArbitrationType_WaitIfEqual64 = 3, }; enum YieldType : s64 { @@ -440,19 +435,15 @@ namespace ams::svc { /* 11.x+ DisableDeviceAddressSpaceMerge. */ CreateProcessFlag_DisableDeviceAddressSpaceMerge = (1 << 12), - /* 18.x EnableAliasRegionExtraSize. */ - CreateProcessFlag_EnableAliasRegionExtraSize = (1 << 13), - /* Mask of all flags. */ - CreateProcessFlag_All = CreateProcessFlag_Is64Bit | - CreateProcessFlag_AddressSpaceMask | - CreateProcessFlag_EnableDebug | - CreateProcessFlag_EnableAslr | - CreateProcessFlag_IsApplication | - CreateProcessFlag_PoolPartitionMask | - CreateProcessFlag_OptimizeMemoryAllocation | - CreateProcessFlag_DisableDeviceAddressSpaceMerge | - CreateProcessFlag_EnableAliasRegionExtraSize, + CreateProcessFlag_All = CreateProcessFlag_Is64Bit | + CreateProcessFlag_AddressSpaceMask | + CreateProcessFlag_EnableDebug | + CreateProcessFlag_EnableAslr | + CreateProcessFlag_IsApplication | + CreateProcessFlag_PoolPartitionMask | + CreateProcessFlag_OptimizeMemoryAllocation | + CreateProcessFlag_DisableDeviceAddressSpaceMerge, }; /* Debug types. */ diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index 4ea900fb7..0268b505a 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(20); - constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 5); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(16); + constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 2); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); diff --git a/libraries/libvapours/include/vapours/types.hpp b/libraries/libvapours/include/vapours/types.hpp index d22f944ab..e7b75a8f0 100644 --- a/libraries/libvapours/include/vapours/types.hpp +++ b/libraries/libvapours/include/vapours/types.hpp @@ -16,6 +16,7 @@ #pragma once #include #include +#include /* NOTE: This file serves as a substitute for libnx . */ diff --git a/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp b/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp index a06b54b5c..543126026 100644 --- a/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp +++ b/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp @@ -157,7 +157,7 @@ namespace ams::util { } else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) { return ::ams::util::impl::LoadAcquireExclusiveForAtomic(p); } else { - static_assert(false, "Invalid memory order"); + static_assert(Order != Order, "Invalid memory order"); } } @@ -172,7 +172,7 @@ namespace ams::util { } else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) { return ::ams::util::impl::StoreReleaseExclusiveForAtomic(p, s); } else { - static_assert(false, "Invalid memory order"); + static_assert(Order != Order, "Invalid memory order"); } } diff --git a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp index 50ebc3727..710050465 100644 --- a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp +++ b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp @@ -22,7 +22,7 @@ namespace ams::util { template struct TypedStorage { - alignas(Align) std::byte _storage[Size]; + typename std::aligned_storage::type _storage; }; template 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 1a2d54846..671e49a84 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) - : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])rhs), [size]"r"(size) + : [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 7fdd814d1..2532415d4 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])rhs), [size]"r"(size) + : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])lhs), [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 74ff84b47..a332d7658 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) - : "m"(*(const u8 (*)[block_count*BlockSize])data), [round_constants]"r"(RoundConstants) + : [round_constants]"r"(RoundConstants) : ); } while (--block_count != 0); diff --git a/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp b/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp index 11d7c4971..b549b99a4 100644 --- a/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp +++ b/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp @@ -68,7 +68,7 @@ namespace ams::dd { if (hos::GetVersion() >= hos::Version_10_0_0) { svc::Size region_size = 0; - R_TRY_CATCH(svc::QueryMemoryMapping(std::addressof(virt_addr), std::addressof(region_size), aligned_addr, aligned_size)) { + R_TRY_CATCH(svc::QueryIoMapping(std::addressof(virt_addr), std::addressof(region_size), aligned_addr, aligned_size)) { /* Official software handles this by returning 0. */ R_CATCH(svc::ResultNotFound) { return 0; } } R_END_TRY_CATCH_WITH_ABORT_UNLESS; diff --git a/mesosphere/build_mesosphere.py b/mesosphere/build_mesosphere.py index db9599763..5b9dd4f7b 100644 --- a/mesosphere/build_mesosphere.py +++ b/mesosphere/build_mesosphere.py @@ -17,16 +17,11 @@ def main(argc, argv): kernel_ldr = f.read() with open(argv[2], 'rb') as f: kernel = f.read() - kernel_metaptr_offset = 4 - assert (kernel_metaptr_offset <= len(kernel) - 0x40) - assert (kernel[kernel_metaptr_offset:kernel_metaptr_offset + 4] == b'MSS1') - kernel_metadata_offset = up('= bss_start) assert (bss_end == kernel_end) @@ -58,9 +53,9 @@ def main(argc, argv): mesosphere_end = align_up(kernel_ldr_end, 0x1000) with open(argv[3], 'wb') as f: - f.write(kernel[:kernel_metadata_offset]) - f.write(pk(' -extern "C" void __rodata_start(); -extern "C" void __rodata_end(); - -extern "C" void __bin_start__(); -extern "C" void __bin_end__(); +extern "C" void _start(); +extern "C" void __end__(); namespace ams::kern { @@ -36,7 +33,6 @@ namespace ams::kern::init { void IdentityMappedFunctionAreaEnd(); size_t GetMiscUnknownDebugRegionSize(); - size_t GetSecureUnknownRegionSize(); void InitializeDebugRegisters(); void InitializeExceptionVectors(); @@ -49,7 +45,7 @@ namespace ams::kern::init { constinit KInitArguments g_init_arguments[cpu::NumCores]; /* Globals for passing data between InitializeCorePhase1 and InitializeCorePhase2. */ - constinit InitialProcessBinaryLayoutWithSize g_phase2_initial_process_binary_meta{}; + constinit InitialProcessBinaryLayout g_phase2_initial_process_binary_layout{}; constinit KPhysicalAddress g_phase2_resource_end_phys_addr = Null; constinit u64 g_phase2_linear_region_phys_to_virt_diff = 0; @@ -90,23 +86,27 @@ namespace ams::kern::init { } void SetupInitialArguments() { - /* Determine whether we're running on a cortex-a53 or a-57. */ - cpu::MainIdRegisterAccessor midr_el1; - const auto implementer = midr_el1.GetImplementer(); - const auto primary_part = midr_el1.GetPrimaryPartNumber(); - const bool needs_cpu_ctlr = (implementer == cpu::MainIdRegisterAccessor::Implementer::ArmLimited) && (primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA57 || primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA53); - /* Get parameters for initial arguments. */ - const u64 cpuactlr = needs_cpu_ctlr ? cpu::GetCpuActlrEl1() : 0; - const u64 cpuectlr = needs_cpu_ctlr ? cpu::GetCpuEctlrEl1() : 0; + const u64 ttbr0 = cpu::GetTtbr0El1(); + const u64 ttbr1 = cpu::GetTtbr1El1(); + const u64 tcr = cpu::GetTcrEl1(); + const u64 mair = cpu::GetMairEl1(); + const u64 cpuactlr = cpu::GetCpuActlrEl1(); + const u64 cpuectlr = cpu::GetCpuEctlrEl1(); + const u64 sctlr = cpu::GetSctlrEl1(); for (s32 i = 0; i < static_cast(cpu::NumCores); ++i) { /* Get the arguments. */ KInitArguments *init_args = g_init_arguments + i; /* Set the arguments. */ + init_args->ttbr0 = ttbr0; + init_args->ttbr1 = ttbr1; + init_args->tcr = tcr; + init_args->mair = mair; init_args->cpuactlr = cpuactlr; init_args->cpuectlr = cpuectlr; + init_args->sctlr = sctlr; init_args->sp = GetInteger(KMemoryLayout::GetMainStackTopAddress(i)) - sizeof(KThread::StackParameters); init_args->entrypoint = reinterpret_cast(::ams::kern::init::InvokeMain); init_args->argument = static_cast(i); @@ -223,31 +223,6 @@ 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); @@ -271,7 +246,7 @@ namespace ams::kern::init { /* Decode the initial state. */ const auto initial_page_allocator_state = *static_cast(initial_state[0]); - g_phase2_initial_process_binary_meta = *static_cast(initial_state[1]); + g_phase2_initial_process_binary_layout = *static_cast(initial_state[1]); /* Restore the page allocator state setup by kernel loader. */ g_initial_page_allocator.InitializeFromState(std::addressof(initial_page_allocator_state)); @@ -292,8 +267,8 @@ namespace ams::kern::init { KMemoryLayout::GetPhysicalMemoryRegionTree().InsertDirectly(KernelPhysicalAddressSpaceBase, KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1); /* Save start and end for ease of use. */ - const uintptr_t code_start_virt_addr = reinterpret_cast(__bin_start__); - const uintptr_t code_end_virt_addr = reinterpret_cast(__bin_end__); + const uintptr_t code_start_virt_addr = reinterpret_cast(_start); + const uintptr_t code_end_virt_addr = reinterpret_cast(__end__); /* Setup the containing kernel region. */ constexpr size_t KernelRegionSize = 1_GB; @@ -373,7 +348,7 @@ namespace ams::kern::init { MESOSPHERE_INIT_ABORT_UNLESS(slab_region_size <= resource_region_size); /* Setup the slab region. */ - const KPhysicalAddress code_start_phys_addr = g_phase2_initial_process_binary_meta.layout.kern_address; + const KPhysicalAddress code_start_phys_addr = init_pt.GetPhysicalAddressOfRandomizedRange(code_start_virt_addr, code_region_size); const KPhysicalAddress code_end_phys_addr = code_start_phys_addr + code_region_size; const KPhysicalAddress slab_start_phys_addr = code_end_phys_addr; const KPhysicalAddress slab_end_phys_addr = slab_start_phys_addr + slab_region_size; @@ -517,21 +492,14 @@ namespace ams::kern::init { MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(slab_end_phys_addr), KSystemControl::SecureAppletMemorySize, KMemoryRegionType_DramKernelSecureAppletMemory)); } - /* Insert a physical region for the unknown debug2 region. */ - const size_t secure_unknown_size = GetSecureUnknownRegionSize(); - const auto secure_unknown_end_phys_addr = secure_applet_end_phys_addr + secure_unknown_size; - if (secure_unknown_size > 0) { - MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_applet_end_phys_addr), secure_unknown_size, KMemoryRegionType_DramKernelSecureUnknown)); - } - /* Determine size available for kernel page table heaps. */ const KPhysicalAddress resource_end_phys_addr = slab_start_phys_addr + resource_region_size; g_phase2_resource_end_phys_addr = resource_end_phys_addr; - const size_t page_table_heap_size = GetInteger(resource_end_phys_addr) - GetInteger(secure_unknown_end_phys_addr); + const size_t page_table_heap_size = GetInteger(resource_end_phys_addr) - GetInteger(secure_applet_end_phys_addr); /* Insert a physical region for the kernel page table heap region */ - MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_unknown_end_phys_addr), page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); + MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_applet_end_phys_addr), page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); /* All DRAM regions that we haven't tagged by this point will be mapped under the linear mapping. Tag them. */ for (auto ®ion : KMemoryLayout::GetPhysicalMemoryRegionTree()) { @@ -597,6 +565,9 @@ namespace ams::kern::init { } } + /* Clear the slab region. */ + std::memset(GetVoidPointer(slab_region_start), 0, slab_region_size); + /* NOTE: Unknown function is called here which is ifdef'd out on retail kernel. */ /* The unknown function is immediately before the function which gets an unknown debug region size, inside this translation unit. */ /* It's likely that this is some kind of initializer for this unknown debug region. */ @@ -619,9 +590,6 @@ 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); @@ -656,10 +624,9 @@ namespace ams::kern::init { /* Set the initial process binary physical address. */ /* NOTE: Nintendo does this after pool partition setup, but it's a requirement that we do it before */ /* to retain compatibility with < 5.0.0. */ - const KPhysicalAddress ini_address = g_phase2_initial_process_binary_meta.layout.address; - const size_t ini_size = g_phase2_initial_process_binary_meta.size; + const KPhysicalAddress ini_address = g_phase2_initial_process_binary_layout.address; MESOSPHERE_INIT_ABORT_UNLESS(ini_address != Null); - SetInitialProcessBinaryPhysicalAddress(ini_address, ini_size); + SetInitialProcessBinaryPhysicalAddress(ini_address); /* Setup all other memory regions needed to arrange the pool partitions. */ SetupPoolPartitionMemoryRegions(); @@ -673,7 +640,7 @@ namespace ams::kern::init { /* Check that the region contains the ini. */ MESOSPHERE_INIT_ABORT_UNLESS(ini_region->GetAddress() <= GetInteger(ini_address)); - MESOSPHERE_INIT_ABORT_UNLESS(GetInteger(ini_address) + ini_size <= ini_region->GetEndAddress()); + MESOSPHERE_INIT_ABORT_UNLESS(GetInteger(ini_address) + InitialProcessBinarySizeMax <= ini_region->GetEndAddress()); MESOSPHERE_INIT_ABORT_UNLESS(ini_region->GetEndAddress() != 0); } @@ -765,8 +732,4 @@ namespace ams::kern::init { return 0; } - size_t GetSecureUnknownRegionSize() { - return 0; - } - } \ No newline at end of file diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index ad483ffc2..a8d80a2e7 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -33,37 +33,7 @@ adr reg, label; \ ldr reg, [reg] -#define LOAD_RELATIVE_FROM_LABEL(reg, reg2, label) \ - adr reg2, label; \ - ldr reg, [reg2]; \ - add reg, reg, reg2 -#define INDIRECT_RELATIVE_CALL(reg, reg2, label) \ - adr reg, label; \ - add reg, reg, reg2; \ - blr reg - -#define SETUP_SYSTEM_REGISTER(_reg, _sr) \ - LOAD_FROM_LABEL(_reg, __sysreg_constant_ ## _sr); \ - msr _sr, _reg - -.section .start, "ax", %progbits -.global _start -_start: - b _ZN3ams4kern4init10StartCore0Emm -__metadata_magic_number: - .ascii "MSS1" /* Magic, if executed as gadget "adds w13, w26, #0x4d4, lsl #12" */ -__metadata_offset: - .word __metadata_begin - _start - -#ifdef ATMOSPHERE_BOARD_NINTENDO_NX -.global _ZN3ams4kern17GetTargetFirmwareEv -.type _ZN3ams4kern17GetTargetFirmwareEv, %function -_ZN3ams4kern17GetTargetFirmwareEv: - adr x0, __metadata_target_firmware - ldr w0, [x0] - ret -#endif .section .crt0.text.start, "ax", %progbits @@ -75,6 +45,43 @@ _ZN3ams4kern4init31IdentityMappedFunctionAreaBeginEv: /* ================ Functions after this line remain identity-mapped after initialization finishes. ================ */ +.global _start +_start: + b _ZN3ams4kern4init10StartCore0Emm +__metadata_begin: + .ascii "MSS0" /* Magic */ +__metadata_ini_offset: + .quad 0 /* INI1 base address. */ +__metadata_kernelldr_offset: + .quad 0 /* Kernel Loader base address. */ +__metadata_target_firmware: + .word 0xCCCCCCCC /* Target firmware. */ +__metadata_kernel_layout: + .word _start - _start /* rx_offset */ + .word __rodata_start - _start /* rx_end_offset */ + .word __rodata_start - _start /* ro_offset */ + .word __data_start - _start /* ro_end_offset */ + .word __data_start - _start /* rw_offset */ + .word __bss_start__ - _start /* rw_end_offset */ + .word __bss_start__ - _start /* bss_offset */ + .word __bss_end__ - _start /* bss_end_offset */ + .word __end__ - _start /* resource_offset */ + .word _DYNAMIC - _start /* dynamic_offset */ + .word __init_array_start - _start /* init_array_offset */ + .word __init_array_end - _start /* init_array_end_offset */ +.if (. - __metadata_begin) != 0x48 + .error "Incorrect Mesosphere Metadata" +.endif + +#ifdef ATMOSPHERE_BOARD_NINTENDO_NX +.global _ZN3ams4kern17GetTargetFirmwareEv +.type _ZN3ams4kern17GetTargetFirmwareEv, %function +_ZN3ams4kern17GetTargetFirmwareEv: + adr x0, __metadata_target_firmware + ldr w0, [x0] + ret +#endif + /* ams::kern::init::StartCore0(uintptr_t, uintptr_t) */ .section .crt0.text._ZN3ams4kern4init10StartCore0Emm, "ax", %progbits .global _ZN3ams4kern4init10StartCore0Emm @@ -112,14 +119,6 @@ _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 @@ -140,35 +139,28 @@ _ZN3ams4kern4init10StartCore0Emm: /* Get the unknown debug region. */ /* TODO: This is always zero in release kernels -- what is this? Is it the device tree buffer? */ mov x21, #0 - nop /* We want to invoke kernel loader. */ adr x0, _start adr x1, __metadata_kernel_layout - LOAD_RELATIVE_FROM_LABEL(x2, x4, __metadata_ini_offset) - LOAD_RELATIVE_FROM_LABEL(x3, x4, __metadata_kernelldr_offset) + LOAD_FROM_LABEL(x2, __metadata_ini_offset) + add x2, x0, x2 + LOAD_FROM_LABEL(x3, __metadata_kernelldr_offset) + add x3, x0, x3 /* Invoke kernel loader. */ blr x3 - /* 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) + bl _ZN3ams4kern4init20InitializeCorePhase1EmPPv /* Get the init arguments for core 0. */ mov x0, xzr - nop - INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init16GetInitArgumentsEi) + bl _ZN3ams4kern4init16GetInitArgumentsEi /* Setup the stack pointer. */ ldr x2, [x0, #(INIT_ARGUMENTS_SP)] @@ -176,25 +168,15 @@ _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) + bl _ZN3ams4kern4init20InitializeCorePhase2Ev /* Get the init arguments for core 0. */ mov x0, xzr - nop - INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init16GetInitArgumentsEi) - - /* Retrieve entrypoint and argument. */ - ldr x1, [x0, #(INIT_ARGUMENTS_ENTRYPOINT)] - ldr x0, [x0, #(INIT_ARGUMENTS_ARGUMENT)] - - /* Set sctlr_el1 and ensure instruction consistency. */ - SETUP_SYSTEM_REGISTER(x3, sctlr_el1) - - dsb sy - isb + bl _ZN3ams4kern4init16GetInitArgumentsEi /* Invoke the entrypoint. */ + ldr x1, [x0, #(INIT_ARGUMENTS_ENTRYPOINT)] + ldr x0, [x0, #(INIT_ARGUMENTS_ARGUMENT)] blr x1 0: /* If we return here, something has gone wrong, so wait forever. */ @@ -233,22 +215,18 @@ _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 - /* Setup system registers using values from constants table. */ - SETUP_SYSTEM_REGISTER(x1, ttbr0_el1) - SETUP_SYSTEM_REGISTER(x1, ttbr1_el1) - SETUP_SYSTEM_REGISTER(x1, tcr_el1) - SETUP_SYSTEM_REGISTER(x1, mair_el1) + /* Setup system registers using values from our KInitArguments. */ + ldr x1, [x20, #(INIT_ARGUMENTS_TTBR0)] + msr ttbr0_el1, x1 + ldr x1, [x20, #(INIT_ARGUMENTS_TTBR1)] + msr ttbr1_el1, x1 + ldr x1, [x20, #(INIT_ARGUMENTS_TCR)] + msr tcr_el1, x1 + ldr x1, [x20, #(INIT_ARGUMENTS_MAIR)] + msr mair_el1, x1 /* Perform cpu-specific setup. */ mrs x1, midr_el1 @@ -262,7 +240,6 @@ _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)] @@ -274,12 +251,13 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: isb /* Load remaining needed fields from the init args. */ + ldr x3, [x20, #(INIT_ARGUMENTS_SCTLR)] ldr x2, [x20, #(INIT_ARGUMENTS_SP)] ldr x1, [x20, #(INIT_ARGUMENTS_ENTRYPOINT)] ldr x0, [x20, #(INIT_ARGUMENTS_ARGUMENT)] /* Set sctlr_el1 and ensure instruction consistency. */ - SETUP_SYSTEM_REGISTER(x3, sctlr_el1) + msr sctlr_el1, x3 dsb sy isb @@ -287,44 +265,12 @@ _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 0: /* If we return here, something has gone wrong, so wait forever. */ b 0b -/* Nintendo places the metadata after StartOthercore. */ -.align 8 - -__metadata_begin: -__metadata_ini_offset: - .quad 0 /* INI1 base address. */ -__metadata_kernelldr_offset: - .quad 0 /* Kernel Loader base address. */ -__metadata_target_firmware: - .word 0xCCCCCCCC /* Target firmware. */ -__metadata_kernel_layout: - .word _start - __metadata_kernel_layout /* rx_offset */ - .word __rodata_start - __metadata_kernel_layout /* rx_end_offset */ - .word __rodata_start - __metadata_kernel_layout /* ro_offset */ - .word __data_start - __metadata_kernel_layout /* ro_end_offset */ - .word __data_start - __metadata_kernel_layout /* rw_offset */ - .word __bss_start__ - __metadata_kernel_layout /* rw_end_offset */ - .word __bss_start__ - __metadata_kernel_layout /* bss_offset */ - .word __bss_end__ - __metadata_kernel_layout /* bss_end_offset */ - .word __end__ - __metadata_kernel_layout /* resource_offset */ - .word _DYNAMIC - __metadata_kernel_layout /* dynamic_offset */ - .word __init_array_start - __metadata_kernel_layout /* init_array_offset */ - .word __init_array_end - __metadata_kernel_layout /* init_array_end_offset */ - .word __sysreg_constant_begin - __metadata_kernel_layout /* sysreg_offset */ -.if (. - __metadata_begin) != 0x48 - .error "Incorrect Mesosphere Metadata" -.endif - - /* TODO: Can we remove this while retaining QEMU support? */ #ifndef ATMOSPHERE_BOARD_NINTENDO_NX /* ams::kern::init::JumpFromEL2ToEL1() */ @@ -402,7 +348,7 @@ _ZN3ams4kern4init16JumpFromEL2ToEL1Ev: mov x0, #0xC5 msr spsr_el2, x0 - ERET_WITH_SPECULATION_BARRIER + eret #endif /* ams::kern::init::DisableMmuAndCaches() */ @@ -413,6 +359,14 @@ _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 */ @@ -430,44 +384,27 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv: mov x30, x22 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::FlushEntireDataCacheLocalWithoutStack() */ @@ -509,27 +446,44 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv: mov x30, x24 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::FlushEntireDataCacheImplWithoutStack() */ @@ -610,24 +564,6 @@ _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv: ret -/* System register values. */ -.align 8 - -__sysreg_constant_begin: -__sysreg_constant_ttbr0_el1: - .quad 0 /* ttbr0_e11. */ -__sysreg_constant_ttbr1_el1: - .quad 0 /* ttbr1_e11. */ -__sysreg_constant_tcr_el1: - .quad 0 /* tcr_e11. */ -__sysreg_constant_mair_el1: - .quad 0 /* mair_e11. */ -__sysreg_constant_sctlr_el1: - .quad 0 /* sctlr_e11. */ -.if (. - __sysreg_constant_begin) != 0x28 - .error "Incorrect System Registers" -.endif - /* ================ Functions before this line remain identity-mapped after initialization finishes. ================ */ /* ams::kern::init::IdentityMappedFunctionAreaEnd() */ 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 5a6b3e7ca..a23cebc0e 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -64,7 +64,7 @@ _ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv: add sp, sp, #(8 * 24) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::EL0A64IrqExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6425EL0A64IrqExceptionHandlerEv, "ax", %progbits @@ -150,7 +150,7 @@ _ZN3ams4kern4arch5arm6425EL0A64IrqExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::EL0A32IrqExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6425EL0A32IrqExceptionHandlerEv, "ax", %progbits @@ -218,7 +218,7 @@ _ZN3ams4kern4arch5arm6425EL0A32IrqExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::EL0SynchronousExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv, "ax", %progbits @@ -331,7 +331,7 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret 4: /* SVC from aarch32. */ ldp x16, x17, [sp], 16 @@ -354,12 +354,21 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: mrs x17, ttbr0_el1 and x17, x17, #(0xFFFF << 48) - /* Invalidate the address held by FAR (and assume it is valid). */ + /* 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. */ 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 @@ -368,7 +377,7 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: ldp x16, x17, [sp], 16 /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::EL1SynchronousExceptionHandler() */ @@ -432,10 +441,9 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: /* Return false. */ mov x0, #0x0 msr elr_el1, x30 - ERET_WITH_SPECULATION_BARRIER + eret 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] @@ -476,16 +484,33 @@ _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 - /* Invalidate the address held by FAR (and assume it is valid). */ + /* 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. */ 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 @@ -494,7 +519,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: mrs x0, tpidr_el1 /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::FpuAccessExceptionHandler() */ @@ -517,7 +542,7 @@ _ZN3ams4kern4arch5arm6425FpuAccessExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::EL1SystemErrorHandler() */ .section .text._ZN3ams4kern4arch5arm6421EL1SystemErrorHandlerEv, "ax", %progbits @@ -655,5 +680,5 @@ _ZN3ams4kern4arch5arm6421EL0SystemErrorHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - ERET_WITH_SPECULATION_BARRIER + eret 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 4b4b1bd3a..080048598 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 @@ -14,7 +14,6 @@ * along with this program. If not, see . */ #include -#include /* ams::kern::arch::arm64::UserModeThreadStarter() */ .section .text._ZN3ams4kern4arch5arm6421UserModeThreadStarterEv, "ax", %progbits @@ -63,7 +62,7 @@ _ZN3ams4kern4arch5arm6421UserModeThreadStarterEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return to EL0 */ - ERET_WITH_SPECULATION_BARRIER + eret /* ams::kern::arch::arm64::SupervisorModeThreadStarter() */ .section .text._ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv, "ax", %progbits @@ -76,9 +75,6 @@ _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 @@ -87,6 +83,7 @@ _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 + /* This should never execute, but Nintendo includes an ERET here. */ + eret diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp index d01ddd151..6adff0754 100644 --- a/mesosphere/kernel/source/kern_kernel_instantiations.cpp +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -111,8 +111,4 @@ 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/kernel_ldr.ld b/mesosphere/kernel_ldr/kernel_ldr.ld index 26802a6f3..c56886133 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.ld +++ b/mesosphere/kernel_ldr/kernel_ldr.ld @@ -12,7 +12,6 @@ SECTIONS /* =========== CODE section =========== */ PROVIDE(__start__ = 0x0); . = __start__; - __bin_start__ = .; __code_start = . ; .crt0 : @@ -75,8 +74,9 @@ SECTIONS .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata .dynamic : { *(.dynamic) } :krnlldr :dyn + .dynsym : { *(.dynsym) } :krnlldr + .dynstr : { *(.dynstr) } :krnlldr .rela.dyn : { *(.rela.*) } :krnlldr - .relr.dyn : { *(.relr.*) } :krnlldr .hash : { *(.hash) } :krnlldr .gnu.hash : { *(.gnu.hash) } :krnlldr .gnu.version : { *(.gnu.version) } :krnlldr @@ -159,7 +159,6 @@ SECTIONS } :krnlldr __bss_end__ = .; - __bin_end__ = .; __end__ = ABSOLUTE(.) ; /* ================== @@ -167,7 +166,7 @@ SECTIONS ================== */ /* Discard sections that difficult post-processing */ - /DISCARD/ : { *(.group .comment .note .interp .dynsym .dynstr) } + /DISCARD/ : { *(.group .comment .note .interp) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/mesosphere/kernel_ldr/kernel_ldr.specs b/mesosphere/kernel_ldr/kernel_ldr.specs index 42d7e341e..1c6fb7205 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.specs +++ b/mesosphere/kernel_ldr/kernel_ldr.specs @@ -1,7 +1,7 @@ %rename link old_link *link: -%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -z pack-relative-relocs -nostdlib +%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib -nostartfiles *startfile: crti%O%s crtbegin%O%s diff --git a/mesosphere/kernel_ldr/source/arch/arm64/start.s b/mesosphere/kernel_ldr/source/arch/arm64/start.s index 27a314721..1a1f4be9d 100644 --- a/mesosphere/kernel_ldr/source/arch/arm64/start.s +++ b/mesosphere/kernel_ldr/source/arch/arm64/start.s @@ -116,29 +116,13 @@ _main: /* X0 is now the saved state. */ /* We will return this to the kernel. */ - /* Adjust return address to point to the relocated kernel. */ + /* Return to the newly-relocated kernel. */ ldr x1, [sp, #0x18] /* Return address to Kernel */ ldr x2, [sp, #0x00] /* Relocated kernel base address diff. */ add x1, x2, x1 - - /* Translate the relocated address back to a physical address. */ - and x4, x1, #0xFFF - sub x3, x1, x4 - at s1e1r, x3 - isb - mrs x3, par_el1 -1: - tbnz w3, #0, 1b - and x3, x3, #0xFFFFFFFFF000 - add x3, x3, x4 - - /* Return the difference between relocated and physical in x1. */ - sub x1, x1, x3 - - /* Setup stack, and return to the kernel. */ ldr x2, [sp, #0x20] mov sp, x2 - br x3 + br x1 #ifdef ATMOSPHERE_BOARD_NINTENDO_NX .global _ZN3ams4kern17GetTargetFirmwareEv diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 43979905c..70e26866c 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -19,8 +19,8 @@ /* Necessary for calculating kernelldr size/base for initial identity mapping */ extern "C" { - extern const u8 __bin_start__[]; - extern const u8 __bin_end__[]; + extern const u8 __start__[]; + extern const u8 __end__[]; } @@ -45,41 +45,16 @@ namespace ams::kern::init::loader { constinit KInitialPageAllocator g_initial_page_allocator; constinit KInitialPageAllocator::State g_final_page_allocator_state; - constinit InitialProcessBinaryLayoutWithSize g_initial_process_binary_meta; + constinit InitialProcessBinaryLayout g_initial_process_binary_layout; constinit void *g_final_state[2]; - 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; - layout->rx_offset += layout_offset; - layout->rx_end_offset += layout_offset; - layout->ro_offset += layout_offset; - layout->ro_end_offset += layout_offset; - layout->rw_offset += layout_offset; - layout->rw_end_offset += layout_offset; - layout->bss_offset += layout_offset; - layout->bss_end_offset += layout_offset; - layout->resource_offset += layout_offset; - layout->dynamic_offset += layout_offset; - layout->init_array_offset += layout_offset; - layout->init_array_end_offset += layout_offset; - layout->sysreg_offset += layout_offset; - } - - /* Relocate the kernel if necessary. */ + void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout) { KPhysicalAddress correct_base = KSystemControl::Init::GetKernelPhysicalBaseAddress(base_address); if (correct_base != base_address) { 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; @@ -87,20 +62,20 @@ namespace ams::kern::init::loader { } } - void SetupInitialIdentityMapping(KInitialPageTable &init_pt, uintptr_t base_address, uintptr_t kernel_size, uintptr_t page_table_region, size_t page_table_region_size, KInitialPageAllocator &allocator, KernelSystemRegisters *sysregs) { + void SetupInitialIdentityMapping(KInitialPageTable &init_pt, uintptr_t base_address, uintptr_t kernel_size, uintptr_t page_table_region, size_t page_table_region_size, KInitialPageAllocator &allocator) { /* Map in an RWX identity mapping for the kernel. */ constexpr PageTableEntry KernelRWXIdentityAttribute(PageTableEntry::Permission_KernelRWX, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); init_pt.Map(base_address, kernel_size, base_address, KernelRWXIdentityAttribute, allocator, 0); /* Map in an RWX identity mapping for ourselves. */ 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, KernelLdrRWXIdentityAttribute, allocator, 0); + const uintptr_t kernel_ldr_base = util::AlignDown(reinterpret_cast(__start__), PageSize); + const uintptr_t kernel_ldr_size = util::AlignUp(reinterpret_cast(__end__), PageSize) - kernel_ldr_base; + init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelRWXIdentityAttribute, 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, PageTableRegionRWAttribute, allocator, 0); + init_pt.Map(page_table_region, page_table_region_size, page_table_region, KernelRWXIdentityAttribute, allocator, 0); /* Place the L1 table addresses in the relevant system registers. */ cpu::SetTtbr0El1(init_pt.GetTtbr0L1TableAddress()); @@ -121,17 +96,9 @@ namespace ams::kern::init::loader { /* Setup SCTLR_EL1. */ /* TODO: Define these bits properly elsewhere, document exactly what each bit set is doing .*/ - constexpr u64 SctlrValue = 0x0000000034D5D92Dul; + constexpr u64 SctlrValue = 0x0000000034D5D925ul; cpu::SetSctlrEl1(SctlrValue); cpu::InstructionMemoryBarrier(); - - /* Setup the system registers for other cores. */ - /* NOTE: sctlr_el1 on other cores has the WXN bit set (0x80000); this will be set before KernelMain() on this core. */ - sysregs->ttbr0_el1 = init_pt.GetTtbr0L1TableAddress(); - sysregs->ttbr1_el1 = init_pt.GetTtbr1L1TableAddress(); - sysregs->tcr_el1 = TcrValue; - sysregs->mair_el1 = MairValue; - sysregs->sctlr_el1 = SctlrValue | 0x80000; } KVirtualAddress GetRandomKernelBaseAddress(KInitialPageTable &page_table, KPhysicalAddress phys_base_address, size_t kernel_size) { @@ -171,7 +138,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, ini_base_address); + RelocateKernelPhysically(base_address, layout); /* Validate kernel layout. */ const uintptr_t rx_offset = layout->rx_offset; @@ -192,38 +159,25 @@ namespace ams::kern::init::loader { const uintptr_t dynamic_offset = layout->dynamic_offset; const uintptr_t init_array_offset = layout->init_array_offset; const uintptr_t init_array_end_offset = layout->init_array_end_offset; - const uintptr_t sysreg_offset = layout->sysreg_offset; /* Determine the size of the resource region. */ const size_t resource_region_size = KMemoryLayout::GetResourceRegionSizeForInit(KSystemControl::Init::ShouldIncreaseThreadResourceLimit()); const uintptr_t resource_end_address = base_address + resource_offset + resource_region_size; /* Setup the INI1 header in memory for the kernel. */ - { - /* Get the kernel layout. */ - KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_meta.layout), base_address); + KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_layout)); + MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_layout.address != 0); - /* If there's no desired base address, use the ini in place. */ - if (g_initial_process_binary_meta.layout.address == 0) { - g_initial_process_binary_meta.layout.address = ini_base_address; - } - - - /* Validate and potentially relocate the INI. */ + if (ini_base_address != g_initial_process_binary_layout.address) { + /* The INI is not at the correct address, so we need to relocate it. */ const InitialProcessBinaryHeader *ini_header = reinterpret_cast(ini_base_address); - size_t ini_size = 0; - if (ini_header->magic == InitialProcessBinaryMagic && (ini_size = ini_header->size) <= InitialProcessBinarySizeMax) { - /* INI is valid, relocate it if necessary. */ - if (ini_base_address != g_initial_process_binary_meta.layout.address) { - std::memmove(reinterpret_cast(g_initial_process_binary_meta.layout.address), ini_header, ini_size); - } + if (ini_header->magic == InitialProcessBinaryMagic && ini_header->size <= InitialProcessBinarySizeMax) { + /* INI is valid, relocate it. */ + std::memmove(reinterpret_cast(g_initial_process_binary_layout.address), ini_header, ini_header->size); } else { /* INI is invalid. Make the destination header invalid. */ - std::memset(reinterpret_cast(g_initial_process_binary_meta.layout.address), 0, sizeof(InitialProcessBinaryHeader)); + std::memset(reinterpret_cast(g_initial_process_binary_layout.address), 0, sizeof(InitialProcessBinaryHeader)); } - - /* Set the INI size in layout. */ - g_initial_process_binary_meta.size = util::AlignUp(ini_size, PageSize); } /* We want to start allocating page tables at the end of the resource region. */ @@ -233,10 +187,7 @@ namespace ams::kern::init::loader { KInitialPageTable init_pt(KernelBaseRangeStart, KernelBaseRangeLast, g_initial_page_allocator); /* 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. */ + SetupInitialIdentityMapping(init_pt, base_address, bss_end_offset, resource_end_address, InitialPageTableRegionSizeMax, g_initial_page_allocator); /* Generate a random slide for the kernel's base address. */ const KVirtualAddress virtual_base_address = GetRandomKernelBaseAddress(init_pt, base_address, bss_end_offset); @@ -287,7 +238,7 @@ namespace ams::kern::init::loader { /* Setup final kernel loader state. */ g_final_state[0] = std::addressof(g_final_page_allocator_state); - g_final_state[1] = std::addressof(g_initial_process_binary_meta); + g_final_state[1] = std::addressof(g_initial_process_binary_layout); return g_final_state; } diff --git a/stratosphere/ams_mitm/source/amsmitm_main.cpp b/stratosphere/ams_mitm/source/amsmitm_main.cpp index 9e0538135..97e735f6e 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 = 12_MB; + constexpr size_t MallocBufferSize = 32_MB; alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize]; } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp index 12f8a0e7c..8ea3b9f28 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp @@ -33,7 +33,6 @@ namespace ams::mitm::bpc { Standard, ToRcm, ToPayload, - ByPmic, }; /* Globals. */ @@ -94,9 +93,6 @@ namespace ams::mitm::bpc { void RebootSystem() { switch (g_reboot_type) { - case RebootType::ByPmic: - exosphere::ForceRebootByPmic(); - break; case RebootType::ToRcm: exosphere::ForceRebootToRcm(); break; @@ -117,11 +113,6 @@ namespace ams::mitm::bpc { } void SetRebootPayload(const void *payload, size_t payload_size) { - /* Mariko does not support reboot-to-payload. */ - if (spl::GetSocType() == spl::SocType_Mariko) { - return; - } - /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -140,9 +131,6 @@ namespace ams::mitm::bpc { } Result LoadRebootPayload() { - /* Mariko does not support reboot-to-payload. */ - R_SUCCEED_IF(spl::GetSocType() == spl::SocType_Mariko) - /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -175,11 +163,6 @@ namespace ams::mitm::bpc { g_reboot_type = RebootType::ToPayload; } - /* TODO: Should we actually allow control over this on mariko? */ - if (spl::GetSocType() == spl::SocType_Mariko) { - g_reboot_type = RebootType::ByPmic; - } - R_SUCCEED(); } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp index da01abc46..8776c9b50 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp @@ -67,6 +67,11 @@ namespace ams::mitm::bpc { /* Wait until initialization is complete. */ mitm::WaitInitialized(); + /* On Mariko, we can't reboot to payload/do exosphere-shutdown...so there is no point in bpc.mitm. */ + if (spl::GetSocType() == spl::SocType_Mariko) { + return; + } + /* Create bpc mitm. */ const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName; 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 ea6f1eb09..d837ada71 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -107,9 +107,9 @@ namespace ams::mitm::socket::resolver { HostName, }; - ams::socket::InAddrT current_address{}; + ams::socket::InAddrT current_address; char current_hostname[0x200]; - u32 work{}; + u32 work; State state = State::BeginLine; for (const char *cur = file_data; *cur != '\x00'; ++cur) { diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp index cba29e380..62fd74ef3 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp @@ -17,7 +17,6 @@ #include "../amsmitm_fs_utils.hpp" #include "fsmitm_romfs.hpp" #include "fsmitm_layered_romfs_storage.hpp" -#include "memlet/memlet.h" namespace ams::mitm::fs { @@ -27,8 +26,6 @@ namespace ams::mitm::fs { namespace { - constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB; - struct ApplicationWithDynamicHeapInfo { ncm::ProgramId program_id; size_t dynamic_app_heap_size; @@ -36,11 +33,6 @@ namespace ams::mitm::fs { }; constexpr const ApplicationWithDynamicHeapInfo ApplicationsWithDynamicHeap[] = { - /* STAR WARS: Knights of the Old Republic II: The Sith Lords. */ - /* Requirement ? MB. 16 MB stolen heap fixes a crash, though. */ - /* Unknown heap sensitivity. */ - { 0x0100B2C016252000, 16_MB, 0_MB }, - /* Animal Crossing: New Horizons. */ /* Requirement ~24 MB. */ /* No particular heap sensitivity. */ @@ -49,7 +41,7 @@ namespace ams::mitm::fs { /* Fire Emblem: Engage. */ /* Requirement ~32+ MB. */ /* No particular heap sensitivity. */ - { 0x0100A6301214E000, 20_MB, 0_MB }, + { 0x0100A6301214E000, 16_MB, 0_MB }, /* The Legend of Zelda: Tears of the Kingdom. */ /* Requirement ~48 MB. */ @@ -93,12 +85,10 @@ 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 || this->heap_size == 0); + AMS_ABORT_UNLESS(this->heap_address != 0); /* Create heap. */ - if (this->heap_size > 0) { - util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); - } + util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); } } @@ -166,52 +156,6 @@ 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{}; @@ -220,7 +164,6 @@ 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) { @@ -232,10 +175,6 @@ 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(); - } } } @@ -244,33 +183,15 @@ 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) { - if (g_building_from_dynamic_heap) { - void *ret = nullptr; - if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) { - ret = g_dynamic_let_heap.Allocate(size); - } + AMS_UNUSED(type); - if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) { - ret = g_dynamic_app_heap.Allocate(size); - } + if (g_building_from_dynamic_heap) { + void *ret = g_dynamic_app_heap.Allocate(size); if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) { ret = g_dynamic_sys_heap.Allocate(size); @@ -290,11 +211,7 @@ namespace ams::mitm::fs { AMS_UNUSED(type); AMS_UNUSED(size); - 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_dynamic_app_heap.TryFree(p)) { if (!g_building_from_dynamic_heap) { g_dynamic_app_heap.TryRelease(); } @@ -1104,7 +1021,6 @@ 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 deleted file mode 100644 index ad14ebb2a..000000000 --- a/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c +++ /dev/null @@ -1,41 +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 . - */ -#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/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h deleted file mode 100644 index 218761936..000000000 --- a/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h +++ /dev/null @@ -1,32 +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 . - */ - -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 deleted file mode 100644 index d7ce9a7a9..000000000 --- a/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h +++ /dev/null @@ -1,65 +0,0 @@ -#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 569ac2f61..4b6d1b8cd 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c @@ -48,29 +48,6 @@ 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; @@ -116,10 +93,6 @@ 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 9cfd2774d..afb8125d3 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h @@ -25,7 +25,6 @@ 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 5613d267e..9568f9108 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,11 +38,6 @@ 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 e9adbe46d..b08669e59 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,11 +18,10 @@ #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) \ - 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) +#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_DEFINE_INTERFACE(ams::mitm::ns::impl, IDocumentInterface, AMS_NS_DOCUMENT_MITM_INTERFACE_INFO, 0x0F9B1C00) @@ -48,7 +47,6 @@ 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/boot/source/boot_power_utils.cpp b/stratosphere/boot/source/boot_power_utils.cpp index 0dc71b842..3f057e87c 100644 --- a/stratosphere/boot/source/boot_power_utils.cpp +++ b/stratosphere/boot/source/boot_power_utils.cpp @@ -16,6 +16,7 @@ #include #include "boot_power_utils.hpp" #include "boot_pmic_driver.hpp" +#include "fusee_bin.h" namespace ams::boot { @@ -31,10 +32,6 @@ namespace ams::boot { /* Globals. */ alignas(os::MemoryPageSize) u8 g_work_page[os::MemoryPageSize]; - constexpr const u8 FuseeBin[] = { - #embed - }; - /* Helpers. */ void ClearIram() { /* Make page FFs. */ @@ -51,8 +48,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - 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))); + 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))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -64,8 +61,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - 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))); + 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))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -96,7 +93,7 @@ namespace ams::boot { } void SetInitialRebootPayload() { - ::ams::SetInitialRebootPayload(FuseeBin, sizeof(FuseeBin)); + ::ams::SetInitialRebootPayload(fusee_bin, fusee_bin_size); } void RebootForFatalError(ams::FatalErrorContext *ctx) { diff --git a/stratosphere/boot/system_module.mk b/stratosphere/boot/system_module.mk index 2f28eeee1..be26006df 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)/*.*))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee.bin #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -67,18 +67,15 @@ endif .PHONY: clean all check_lib check_fusee #--------------------------------------------------------------------------------- -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 +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 +$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib check_fusee @$(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 @@ -127,7 +124,15 @@ $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR @npdmtool $< $@ @echo built ... $(notdir $@) -boot_power_utils.o: CXXFLAGS += --embed-dir="$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/" +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) -include $(DEPENDS) diff --git a/stratosphere/creport/creport.json b/stratosphere/creport/creport.json index 99859c3d2..cdd28371d 100644 --- a/stratosphere/creport/creport.json +++ b/stratosphere/creport/creport.json @@ -110,7 +110,6 @@ "type": "debug_flags", "value": { "allow_debug": false, - "force_debug_prod": false, "force_debug": true } } diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index fec6cbc67..9936102e5 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -26,8 +26,6 @@ namespace ams::creport { static_assert(DyingMessageAddressOffset == AMS_OFFSETOF(ams::svc::aarch64::ProcessLocalRegion, dying_message_region_address)); static_assert(DyingMessageAddressOffset == AMS_OFFSETOF(ams::svc::aarch32::ProcessLocalRegion, dying_message_region_address)); - constexpr size_t CrashReportDataCacheSize = 256_KB; - /* Helper functions. */ bool TryGetCurrentTimestamp(u64 *out) { /* Clear output. */ @@ -309,15 +307,7 @@ namespace ams::creport { /* Save crash report. */ util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, m_process_info.program_id); { - /* Try to allocate data cache. */ - void * const data_cache = lmem::AllocateFromExpHeap(m_heap_handle, CrashReportDataCacheSize + os::MemoryPageSize); - ON_SCOPE_EXIT { if (data_cache != nullptr) { lmem::FreeToExpHeap(m_heap_handle, data_cache); } }; - - /* Align up the data cache. This is safe because null will align up to null. */ - void * const aligned_cache = reinterpret_cast(util::AlignUp(reinterpret_cast(data_cache), os::MemoryPageSize)); - - /* Open and save the file using the cache. */ - ScopedFile file(file_path, aligned_cache, aligned_cache != nullptr ? CrashReportDataCacheSize : 0); + ScopedFile file(file_path); if (file.IsOpen()) { this->SaveToFile(file); } diff --git a/stratosphere/creport/source/creport_modules.cpp b/stratosphere/creport/source/creport_modules.cpp index 7ea58e0dd..69620b92b 100644 --- a/stratosphere/creport/source/creport_modules.cpp +++ b/stratosphere/creport/source/creport_modules.cpp @@ -46,7 +46,7 @@ namespace ams::creport { } void ModuleList::SaveToFile(ScopedFile &file) { - file.WriteFormat(" Number of Modules: %02zu\n", m_num_modules); + file.WriteFormat(" Number of Modules: %zu\n", m_num_modules); for (size_t i = 0; i < m_num_modules; i++) { const auto& module = m_modules[i]; file.WriteFormat(" Module %02zu:\n", i); @@ -282,38 +282,56 @@ namespace ams::creport { return; } + /* Read the first instruction of .text. */ + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address, sizeof(temp_32)))) { + return; + } + /* We want to find the symbol table/.dynamic. */ uintptr_t dyn_address = 0; uintptr_t sym_tab = 0; uintptr_t str_tab = 0; size_t num_sym = 0; - /* Locate .dyn using rocrt::ModuleHeader. */ - { - /* Determine the ModuleHeader offset. */ + /* Detect module type. */ + if (temp_32 == 0) { + /* Module is dynamically loaded by rtld. */ u32 mod_offset; if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(mod_offset)), m_debug_handle, module.start_address + sizeof(u32), sizeof(u32)))) { return; } - /* Read the signature. */ - constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + SignatureFieldOffset, sizeof(u32)))) { + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset, sizeof(u32)))) { return; } - /* Check that the module signature is expected. */ if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ return; } - /* Determine the dynamic offset. */ - constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + DynamicFieldOffset, sizeof(u32)))) { + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + sizeof(u32), sizeof(u32)))) { return; } dyn_address = module.start_address + mod_offset + temp_32; + } else if (temp_32 == 0x14000002) { + /* Module embeds rtld. */ + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x5C, sizeof(u32)))) { + return; + } + + if (temp_32 != 0x94000002) { + return; + } + + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x60, sizeof(u32)))) { + return; + } + + dyn_address = module.start_address + 0x60 + temp_32; + } else { + /* Module has unknown format. */ + return; } diff --git a/stratosphere/creport/source/creport_scoped_file.cpp b/stratosphere/creport/source/creport_scoped_file.cpp index 1b6341c99..4daf9e046 100644 --- a/stratosphere/creport/source/creport_scoped_file.cpp +++ b/stratosphere/creport/source/creport_scoped_file.cpp @@ -60,24 +60,22 @@ namespace ams::creport { /* Print the line prefix. */ if (first) { - this->Write(prefix, prefix_len); + this->WriteFormat("%s", prefix); first = false; } else { - std::memset(g_format_buffer, ' ', prefix_len); - this->Write(g_format_buffer, prefix_len); + this->WriteFormat("%*s", prefix_len, ""); } /* Dump up to 0x20 of hex memory. */ { char hex[MaximumLineLength * 2 + 2] = {}; for (size_t i = 0; i < cur_size; i++) { - hex[i * 2 + 0] = "0123456789ABCDEF"[data_u8[data_ofs] >> 4]; - hex[i * 2 + 1] = "0123456789ABCDEF"[data_u8[data_ofs] & 0xF]; - ++data_ofs; + util::SNPrintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]); } hex[cur_size * 2 + 0] = '\n'; + hex[cur_size * 2 + 1] = '\x00'; - this->Write(hex, cur_size * 2 + 1); + this->WriteString(hex); } /* Continue. */ @@ -85,40 +83,16 @@ namespace ams::creport { } } - void ScopedFile::Write(const void *data, size_t size) { /* If we're not open, we can't write. */ if (!this->IsOpen()) { return; } - /* If we have a cache, write to it. */ - if (m_cache != nullptr) { - /* Write into the cache, if we can. */ - if (m_cache_size - m_cache_offset >= size || R_SUCCEEDED(this->TryWriteCache())) { - std::memcpy(m_cache + m_cache_offset, data, size); - m_cache_offset += size; - } - } else { - /* Advance, if we write successfully. */ - if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::None))) { - m_offset += size; - } + /* Advance, if we write successfully. */ + if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::Flush))) { + m_offset += size; } } - Result ScopedFile::TryWriteCache() { - /* If there's no cached data, there's nothing to do. */ - R_SUCCEED_IF(m_cache_offset == 0); - - /* Try to write any cached data. */ - R_TRY(fs::WriteFile(m_file, m_offset, m_cache, m_cache_offset, fs::WriteOption::None)); - - /* Update our extents. */ - m_offset += m_cache_offset; - m_cache_offset = 0; - - R_SUCCEED(); - } - } \ No newline at end of file diff --git a/stratosphere/creport/source/creport_scoped_file.hpp b/stratosphere/creport/source/creport_scoped_file.hpp index 5adcbeb09..7b302b589 100644 --- a/stratosphere/creport/source/creport_scoped_file.hpp +++ b/stratosphere/creport/source/creport_scoped_file.hpp @@ -25,11 +25,8 @@ namespace ams::creport { fs::FileHandle m_file; s64 m_offset; bool m_opened; - u8 *m_cache; - const size_t m_cache_size; - s64 m_cache_offset; public: - ScopedFile(const char *path, void *cache = nullptr, size_t cache_size = 0) : m_file(), m_offset(), m_opened(false), m_cache(static_cast(cache)), m_cache_size(cache_size), m_cache_offset(0) { + ScopedFile(const char *path) : m_file(), m_offset(), m_opened(false) { if (R_SUCCEEDED(fs::CreateFile(path, 0))) { m_opened = R_SUCCEEDED(fs::OpenFile(std::addressof(m_file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend)); } @@ -37,10 +34,6 @@ namespace ams::creport { ~ScopedFile() { if (m_opened) { - if (m_cache != nullptr) { - this->TryWriteCache(); - } - fs::FlushFile(m_file); fs::CloseFile(m_file); } } @@ -54,8 +47,6 @@ namespace ams::creport { void DumpMemory(const char *prefix, const void *data, size_t size); void Write(const void *data, size_t size); - private: - Result TryWriteCache(); }; } \ No newline at end of file diff --git a/stratosphere/dmnt.gen2/dmnt.gen2.json b/stratosphere/dmnt.gen2/dmnt.gen2.json index e0d970789..918f1262c 100644 --- a/stratosphere/dmnt.gen2/dmnt.gen2.json +++ b/stratosphere/dmnt.gen2/dmnt.gen2.json @@ -105,7 +105,6 @@ "type": "debug_flags", "value": { "allow_debug": false, - "force_debug_prod": false, "force_debug": true } }] diff --git a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp index 956226448..f13a59508 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp @@ -45,7 +45,7 @@ namespace ams::dmnt { } if (R_FAILED(result)) { - AMS_DMNT2_GDB_LOG_DEBUG("BreakPointManager::SetBreakPoint %p 0x%lx !!! Fail 0x%08x !!!\n", bp, address, result.GetValue()); + AMS_DMNT2_GDB_LOG_DEBUG("BreakPointManager::SetBreakPoint %p 0x%lx !!! Fail 0x%08x !!!\n", bp, bp->m_address, result.GetValue()); } R_RETURN(result); diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp index 757a237a8..379687bde 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp @@ -1538,18 +1538,13 @@ namespace ams::dmnt { } void GdbServerImpl::Q() { - if (ParsePrefix(m_receive_packet, "QStartNoAckMode")) { - this->QStartNoAckMode(); + if (false) { + /* TODO: QStartNoAckMode? */ } else { AMS_DMNT2_GDB_LOG_DEBUG("Not Implemented Q: %s\n", m_receive_packet); } } - void GdbServerImpl::QStartNoAckMode() { - m_packet_io.SetNoAck(); - AppendReplyOk(m_reply_cur, m_reply_end); - } - void GdbServerImpl::T() { if (const char *dot = std::strchr(m_receive_packet, '.'); dot != nullptr) { const u64 thread_id = DecodeHex(dot + 1); @@ -1924,7 +1919,6 @@ namespace ams::dmnt { R_SUCCEED(); } - void GdbServerImpl::q() { if (ParsePrefix(m_receive_packet, "qAttached:")) { this->qAttached(); @@ -2111,24 +2105,9 @@ namespace ams::dmnt { ParsePrefix(command, "0x"); /* Decode program id. */ - const ncm::ProgramId program_id(DecodeHex(command)); + const u64 program_id = DecodeHex(command); - /* Wait for the process to be created. */ - { - /* Get hook to creation of process with program id. */ - os::NativeHandle h; - R_ABORT_UNLESS(pm::dmnt::HookToCreateProcess(std::addressof(h), program_id)); - - /* Wait for event. */ - os::SystemEvent hook_event(h, true, os::InvalidNativeHandle, false, os::EventClearMode_AutoClear); - hook_event.Wait(); - } - - /* Get process id. */ - R_ABORT_UNLESS(pm::dmnt::GetProcessId(std::addressof(m_wait_process_id), program_id)); - - /* Note that we're attaching. */ - AppendReplyFormat(reply_cur, reply_end, "Send `attach 0x%lx` to attach.\n", m_wait_process_id.value); + AppendReplyFormat(reply_cur, reply_end, "[TODO] wait for program id 0x%lx\n", program_id); } else { std::memcpy(m_reply_cur, command, std::strlen(command) + 1); AppendReplyFormat(reply_cur, reply_end, "Unknown command `%s`\n", m_reply_cur); @@ -2151,7 +2130,6 @@ namespace ams::dmnt { AppendReplyFormat(m_reply_cur, m_reply_end, ";swbreak+"); AppendReplyFormat(m_reply_cur, m_reply_end, ";hwbreak+"); AppendReplyFormat(m_reply_cur, m_reply_end, ";vContSupported+"); - AppendReplyFormat(m_reply_cur, m_reply_end, ";QStartNoAckMode+"); } void GdbServerImpl::qXfer() { diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp index e0648cd1d..5aca349e5 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp @@ -77,8 +77,6 @@ namespace ams::dmnt { void Q(); - void QStartNoAckMode(); - void T(); void Z(); @@ -117,4 +115,4 @@ namespace ams::dmnt { Result ParseVCont(char * const token, u64 *thread_ids, u8 *continue_modes, s32 num_threads, DebugProcess::ContinueMode &default_continue_mode); }; -} +} \ No newline at end of file diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index c1ecfb675..2d56ab4c6 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -46,11 +46,8 @@ namespace ams::dmnt::cheat::impl { void CheatVirtualMachine::OpenDebugLogFile() { #ifdef DMNT_CHEAT_VM_DEBUG_LOG CloseDebugLogFile(); - fs::EnsureDirectory("sdmc:/atmosphere/cheat_vm_logs"); - fs::CreateFile("sdmc:/atmosphere/cheat_vm_logs/debug_log.txt", 0); - R_ABORT_UNLESS(fs::OpenFile(std::addressof(m_debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt", fs::OpenMode_Write | fs::OpenMode_AllowAppend)); + R_ABORT_UNLESS(fs::OpenFile(std::addressof(m_debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt")); m_debug_log_file_offset = 0; - m_has_debug_log_file = true; #endif } @@ -83,8 +80,7 @@ namespace ams::dmnt::cheat::impl { fmt_len += 1; } - fs::WriteFile(m_debug_log_file, m_debug_log_file_offset, m_debug_log_format_buf, fmt_len, fs::WriteOption::Flush); - m_debug_log_file_offset += fmt_len; + fs::WriteFile(m_debug_log_file, m_debug_log_offset, m_debug_log_format_buf, fmt_len, fs::WriteOption::Flush); #else AMS_UNUSED(format); #endif @@ -108,8 +104,6 @@ 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; @@ -160,11 +154,6 @@ 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); @@ -365,7 +354,6 @@ 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; @@ -395,8 +383,6 @@ 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); } @@ -437,8 +423,7 @@ 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); - opcode.ldr_memory.offset_register = ((first_dword >> 8) & 0xF); + opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0; opcode.ldr_memory.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); } break; @@ -471,14 +456,6 @@ 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)) */ @@ -753,8 +730,6 @@ 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; } } @@ -790,7 +765,6 @@ namespace ams::dmnt::cheat::impl { return true; } - static u64 s_keyold = 0; void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) { CheatVmOpcode cur_opcode; u64 kHeld = 0; @@ -846,7 +820,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.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_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, cur_opcode.begin_cond.rel_address); u64 src_value = 0; switch (cur_opcode.store_static.bit_width) { case 1: @@ -918,12 +892,8 @@ namespace ams::dmnt::cheat::impl { { /* Choose source address. */ u64 src_address; - if (cur_opcode.ldr_memory.load_from_reg == 1) { + if (cur_opcode.ldr_memory.load_from_reg) { 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); } @@ -1008,18 +978,6 @@ 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]; @@ -1060,34 +1018,6 @@ 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; } @@ -1370,7 +1300,6 @@ 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 2dd958d5c..0eb47b2a2 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -43,7 +43,6 @@ 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. */ @@ -60,7 +59,6 @@ namespace ams::dmnt::cheat::impl { MemoryAccessType_Heap = 1, MemoryAccessType_Alias = 2, MemoryAccessType_Aslr = 3, - MemoryAccessType_NonRelative = 4, }; enum ConditionalComparisonType : u32 { @@ -86,10 +84,6 @@ 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 { @@ -144,8 +138,6 @@ 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; }; @@ -169,8 +161,7 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; u32 reg_index; - u8 load_from_reg; - u8 offset_register; + bool load_from_reg; u64 rel_address; }; @@ -194,11 +185,6 @@ namespace ams::dmnt::cheat::impl { u32 key_mask; }; - struct BeginExtendedKeypressConditionalOpcode { - u64 key_mask; - bool auto_repeat; - }; - struct PerformArithmeticRegisterOpcode { u32 bit_width; RegisterArithmeticType math_type; @@ -273,7 +259,6 @@ 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 aef307a68..45b718089 100644 --- a/stratosphere/fatal/fatal.json +++ b/stratosphere/fatal/fatal.json @@ -104,7 +104,6 @@ "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 b3bc25e65..c1693c7b4 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -308,19 +308,10 @@ namespace ams::ldr { ); DEFINE_CAPABILITY_CLASS(DebugFlags, - DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_CAPABILITY_FIELD(ForceDebugProd, AllowDebug, 1, bool); - DEFINE_CAPABILITY_FIELD(ForceDebug, ForceDebugProd, 1, bool); + DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_CAPABILITY_FIELD(ForceDebug, AllowDebug, 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]); @@ -328,14 +319,12 @@ namespace ams::ldr { return (restriction.GetValue() & this->GetValue()) == this->GetValue(); } } - return false; } - static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug_prod, bool force_debug) { + static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug) { util::BitPack32 encoded{IdBitsValue}; encoded.Set(allow_debug); - encoded.Set(force_debug_prod); encoded.Set(force_debug); return encoded; } @@ -417,21 +406,7 @@ 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).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); + kac[i] = CapabilityDebugFlags::Encode((flags & ProgramInfoFlag_AllowDebug) != 0, CapabilityDebugFlags::Decode(cap).GetForceDebug()); break; default: break; @@ -443,7 +418,15 @@ namespace ams::ldr { for (size_t i = 0; i < count; ++i) { const auto cap = kac[i]; switch (GetCapabilityId(cap)) { - /* NOTE: Currently, there is no pre-processing necessary. */ + case CapabilityId::MapRegion: + { + /* MapRegion was added in 8.0.0+, and is only allowed under kernels which have the relevant mappings. */ + /* However, we allow it under all firmwares on mesosphere, to facilitate KTrace usage by hbl. */ + if (!svc::IsKTraceEnabled()) { + kac[i] = EmptyCapability; + } + } + break; default: break; } diff --git a/stratosphere/loader/source/ldr_capabilities.hpp b/stratosphere/loader/source/ldr_capabilities.hpp index 21748a7fb..0a91b23cc 100644 --- a/stratosphere/loader/source/ldr_capabilities.hpp +++ b/stratosphere/loader/source/ldr_capabilities.hpp @@ -23,8 +23,6 @@ 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 f1d0dfa14..75260f0b7 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, 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) : 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); } - 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(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o) : 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); } ScopedCodeMount::~ScopedCodeMount() { @@ -46,28 +46,25 @@ namespace ams::ldr { } } - Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { + Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc) { /* 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, attrs)); - - /* Get the content attributes. */ - const auto content_attributes = attrs.content_attributes; + R_TRY(GetProgramPath(content_path, sizeof(content_path), loc)); /* 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, static_cast(loc.storage_id), m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); + R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, fs::ContentAttributes_None, loc.program_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, static_cast(loc.storage_id))); + R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, fs::ContentAttributes_None, loc.program_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, static_cast(loc.storage_id)))) { + if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, fs::ContentAttributes_None, loc.program_id))) { m_mounted_code = true; } @@ -83,7 +80,7 @@ namespace ams::ldr { } /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc) { /* Check for storage id none. */ if (static_cast(loc.storage_id) == ncm::StorageId::None) { std::memset(out_path, 0, out_size); @@ -91,10 +88,6 @@ namespace ams::ldr { R_SUCCEED(); } - /* Get the content attributes. */ - const auto content_attributes = attrs.content_attributes; - AMS_UNUSED(content_attributes); - lr::Path path; /* Check that path registration is allowable. */ diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index d20c80709..f2163776f 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, const ldr::ProgramAttributes &attrs); - ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs); + ScopedCodeMount(const ncm::ProgramLocation &loc); + ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); ~ScopedCodeMount(); Result GetResult() const { @@ -59,24 +59,20 @@ namespace ams::ldr { return m_base_code_verification_data; } private: - Result Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); + Result Initialize(const ncm::ProgramLocation &loc); void EnsureOverrideStatus(const ncm::ProgramLocation &loc); }; - constexpr inline const char * const AtmosphereCodeMountName = "ams-code"; - constexpr inline const char * const AtmosphereCompatMountName = "ams-cmpt"; - constexpr inline const char * const SdOrCodeMountName = "sd-code"; - constexpr inline const char * const CodeMountName = "code"; - constexpr inline const char * const CompatMountName = "cmpt"; + constexpr inline const char * const AtmosphereCodeMountName = "ams-code"; + constexpr inline const char * const SdOrCodeMountName = "sd-code"; + constexpr inline const char * const CodeMountName = "code"; #define ENCODE_ATMOSPHERE_CODE_PATH(relative) "ams-code:" relative - #define ENCODE_ATMOSPHERE_CMPT_PATH(relative) "ams-cmpt:" relative #define ENCODE_SD_OR_CODE_PATH(relative) "sd-code:" relative #define ENCODE_CODE_PATH(relative) "code:" relative - #define ENCODE_CMPT_PATH(relative) "cmpt:" relative /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc); Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc); Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc); diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index efb05efef..66e9bc633 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -54,31 +54,6 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_16_0_0[] = { { 0x7208, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; -constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_17_0_0[] = { - { 0x7170, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, - { 0x71EC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, -}; - -constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_18_0_0[] = { - { 0x6DCC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, - { 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 EmbeddedPatchEntry Usb30ForceEnablePatches_20_1_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 }, @@ -89,9 +64,4 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("1C97AFF30D48AFFEB74B28A530D30ABA0ABB9FFF"), util::size(Usb30ForceEnablePatches_14_0_0), Usb30ForceEnablePatches_14_0_0 }, /* 14.0.0 */ { ParseModuleId("30B15A83E94D91750E7470795414AD1AE9C6A8DB"), util::size(Usb30ForceEnablePatches_15_0_0), Usb30ForceEnablePatches_15_0_0 }, /* 15.0.0 */ { 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 */ - { ParseModuleId("A5EF8D22EDF8A384E4135270ED596C1D2D524159"), util::size(Usb30ForceEnablePatches_20_1_0), Usb30ForceEnablePatches_20_1_0 }, /* 20.1.0 - 20.1.1 */ }; diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 17a4a9160..61c849799 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -27,24 +27,11 @@ namespace ams::ldr { constinit ArgumentStore g_argument_store; - 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; - } - - return true; - } - } - 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()); + Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) { + /* Declare program path, which we'll need later. */ /* Get the location and override status. */ ncm::ProgramLocation loc; @@ -53,28 +40,25 @@ namespace ams::ldr { /* Get the program path. */ char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + R_TRY(GetProgramPath(path, sizeof(path), loc)); 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)); + R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit)); } - 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()); - + Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { /* Zero output. */ std::memset(out, 0, sizeof(*out)); /* Get the program path. */ char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + R_TRY(GetProgramPath(path, sizeof(path), loc)); path[sizeof(path) - 1] = '\x00'; /* Get the program info. */ cfg::OverrideStatus status; - R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, attrs)); + R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path)); if (loc.program_id != out->program_id) { /* Redirect the program path. */ @@ -83,7 +67,7 @@ namespace ams::ldr { /* 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)); + R_TRY(this->SetProgramArgument(new_loc.program_id, entry->argument, entry->argument_size)); } } diff --git a/stratosphere/loader/source/ldr_loader_service.hpp b/stratosphere/loader/source/ldr_loader_service.hpp index 9f5314c55..bad74cd80 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, const ProgramAttributes &attrs) { + Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h) { /* 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(), attrs)); + R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle())); } - 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 GetProgramInfo(sf::Out out_program_info, const ncm::ProgramLocation &loc) { + R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc)); } 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, const ProgramAttributes &attrs) { - R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc, attrs)); + 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 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, const ProgramAttributes &attrs); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs); + 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 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 5e4d8ca06..5b6001f93 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 = 0x420; + static constexpr size_t PointerBufferSize = 0x400; 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 04e71d38b..8d1e5c31a 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -55,8 +55,21 @@ namespace ams::ldr { R_UNLESS(npdm->magic == Npdm::Magic, ldr::ResultInvalidMeta()); /* Validate flags. */ - constexpr u32 InvalidMetaFlagMask = 0x80000000; - R_UNLESS(!(npdm->flags & InvalidMetaFlagMask), ldr::ResultInvalidMeta()); + u32 mask; + if (hos::GetVersion() >= hos::Version_11_0_0) { + /* 11.0.0 added bit 5 = "DisableDeviceAddressSpaceMerge". */ + mask = ~0x3F; + } else if (hos::GetVersion() >= hos::Version_7_0_0) { + /* 7.0.0 added bit 4 = "UseOptimizedMemory" */ + mask = ~0x1F; + } else { + mask = ~0xF; + } + + /* We set the "DisableDeviceAddressSpaceMerge" bit on all versions, so be permissive with it. */ + mask &= ~0x20; + + R_UNLESS(!(npdm->flags & mask), ldr::ResultInvalidMeta()); /* Validate Acid extents. */ R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid))); @@ -77,8 +90,8 @@ namespace ams::ldr { } /* Validate that the acid version is correct. */ - constexpr u8 SupportedSdkMajorVersion = ams::svc::ConvertToSdkMajorVersion(ams::svc::SupportedKernelMajorVersion); - if (acid->unknown_209 < SupportedSdkMajorVersion) { + constexpr u8 MinimumValueForAcid209 = 14; /* TODO: What is the actual meaning of this value? */ + if (acid->unknown_209 < MinimumValueForAcid209) { R_UNLESS(acid->version == 0, ldr::ResultInvalidMeta()); R_UNLESS(acid->unknown_209 == 0, ldr::ResultInvalidMeta()); } @@ -103,30 +116,22 @@ namespace ams::ldr { R_SUCCEED(); } - const u8 *GetAcidSignatureModulus(ncm::ContentMetaPlatform platform, u8 key_generation, bool unk_unused) { - return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused); + const u8 *GetAcidSignatureModulus(u32 key_generation) { + return fssystem::GetAcidSignatureKeyModulus(!IsDevelopmentForAcidSignatureCheck(), key_generation); } - size_t GetAcidSignatureModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { - return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused); - } - - Result ValidateAcidSignature(Meta *meta, ncm::ContentMetaPlatform platform, bool unk_unused) { + Result ValidateAcidSignature(Meta *meta) { /* 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(); } - /* Get the signature key generation. */ - const auto signature_key_generation = meta->npdm->signature_key_generation; - R_UNLESS(fssystem::IsValidSignatureKeyGeneration(platform, signature_key_generation), ldr::ResultInvalidMeta()); - /* Verify the signature. */ const u8 *sig = meta->acid->signature; const size_t sig_size = sizeof(meta->acid->signature); - const u8 *mod = GetAcidSignatureModulus(platform, signature_key_generation, unk_unused); - const size_t mod_size = GetAcidSignatureModulusSize(platform, unk_unused); + const u8 *mod = GetAcidSignatureModulus(meta->npdm->signature_key_generation); + const size_t mod_size = fssystem::AcidSignatureKeyModulusSize; const u8 *exp = fssystem::GetAcidSignatureKeyPublicExponent(); const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize; const u8 *msg = meta->acid->modulus; @@ -190,10 +195,7 @@ namespace ams::ldr { } /* API. */ - 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 = {}; - + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { /* Try to load meta from file. */ fs::FileHandle file; R_TRY(fs::OpenFile(std::addressof(file), AtmosphereMetaPath, fs::OpenMode_Read)); @@ -252,10 +254,6 @@ 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. */ @@ -263,7 +261,7 @@ namespace ams::ldr { R_TRY(fs::OpenFile(std::addressof(file), BaseMetaPath, fs::OpenMode_Read)); ON_SCOPE_EXIT { fs::CloseFile(file); }; R_TRY(LoadMetaFromFile(file, std::addressof(g_original_meta_cache))); - R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta), platform, unk_unused)); + R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta))); meta->modulus = g_original_meta_cache.meta.modulus; meta->check_verification_data = g_original_meta_cache.meta.check_verification_data; } @@ -282,9 +280,9 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform) { + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { if (g_cached_program_id != loc.program_id || g_cached_override_status != status) { - R_RETURN(LoadMeta(out_meta, loc, status, platform, false)); + R_RETURN(LoadMeta(out_meta, loc, status)); } *out_meta = g_meta_cache.meta; R_SUCCEED(); diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp index 4d3ce3fb8..7356185da 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, ncm::ContentMetaPlatform platform, bool unk_unused); - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform); + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); void InvalidateMetaCache(); } diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 5f6f2226b..58e4cf955 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -34,43 +34,23 @@ namespace ams::ldr { enum NsoIndex { Nso_Rtld = 0, Nso_Main = 1, - Nso_Compat0 = 2, - Nso_Compat1 = 3, - Nso_Compat2 = 4, - Nso_Compat3 = 5, - Nso_Compat4 = 6, - Nso_Compat5 = 7, - Nso_Compat6 = 8, - Nso_Compat7 = 9, - Nso_Compat8 = 10, - Nso_Compat9 = 11, - Nso_SubSdk0 = 12, - Nso_SubSdk1 = 13, - Nso_SubSdk2 = 14, - Nso_SubSdk3 = 15, - Nso_SubSdk4 = 16, - Nso_SubSdk5 = 17, - Nso_SubSdk6 = 18, - Nso_SubSdk7 = 19, - Nso_SubSdk8 = 20, - Nso_SubSdk9 = 21, - Nso_Sdk = 22, + Nso_SubSdk0 = 2, + Nso_SubSdk1 = 3, + Nso_SubSdk2 = 4, + Nso_SubSdk3 = 5, + Nso_SubSdk4 = 6, + Nso_SubSdk5 = 7, + Nso_SubSdk6 = 8, + Nso_SubSdk7 = 9, + Nso_SubSdk8 = 10, + Nso_SubSdk9 = 11, + Nso_Sdk = 12, Nso_Count, }; constexpr inline const char *NsoPaths[Nso_Count] = { ENCODE_ATMOSPHERE_CODE_PATH("/rtld"), ENCODE_ATMOSPHERE_CODE_PATH("/main"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat0"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat1"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat2"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat3"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat4"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat5"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat6"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat7"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat8"), - ENCODE_ATMOSPHERE_CMPT_PATH("/compat9"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk0"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk1"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk2"), @@ -380,11 +360,6 @@ namespace ams::ldr { flags |= svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; } - /* 18.0.0+/meso Set Alias region extra size. */ - if (meta_flags & Npdm::MetaFlag_EnableAliasRegionExtraSize) { - flags |= svc::CreateProcessFlag_EnableAliasRegionExtraSize; - } - *out = flags; R_SUCCEED(); } @@ -555,7 +530,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, bool prevent_code_reads) { + Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size) { /* Map and read data from file. */ { /* Map the process memory. */ @@ -594,7 +569,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, prevent_code_reads ? os::MemoryPermission_ExecuteOnly : os::MemoryPermission_ReadExecute)); + R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->text_dst_offset, text_size, 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 +581,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument, bool prevent_code_reads) { + Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument) { /* Load each NSO. */ for (size_t i = 0; i < Nso_Count; i++) { if (has_nso[i]) { @@ -614,7 +589,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], prevent_code_reads)); + R_TRY(LoadAutoLoadModule(process_info->process_handle, file, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i])); } } @@ -658,21 +633,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, (meta->npdm->flags & ldr::Npdm::MetaFlag_PreventCodeReads) != 0)); + R_RETURN(LoadAutoLoadModules(out, nso_headers, has_nso, argument)); } } /* 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, const ldr::ProgramAttributes &attrs) { + 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) { /* Mount code. */ AMS_UNUSED(path); - ScopedCodeMount mount(loc, override_status, attrs); + ScopedCodeMount mount(loc, override_status); R_TRY(mount.GetResult()); /* Load meta, possibly from cache. */ Meta meta; - R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, attrs.platform)); + R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status)); /* Validate meta. */ R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData())); @@ -720,16 +695,16 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs) { + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path) { Meta meta; /* Load Meta. */ { AMS_UNUSED(path); - ScopedCodeMount mount(loc, attrs); + ScopedCodeMount mount(loc); R_TRY(mount.GetResult()); - R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), attrs.platform, false)); + R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus())); 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 0d24c7720..f700dba15 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, const ldr::ProgramAttributes &attrs); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs); + 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); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path); 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 deleted file mode 100644 index d681240e5..000000000 --- a/stratosphere/memlet/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -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 deleted file mode 100644 index 8f44c0ce2..000000000 --- a/stratosphere/memlet/memlet.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "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 deleted file mode 100644 index ea0ee7c10..000000000 --- a/stratosphere/memlet/source/memlet_main.cpp +++ /dev/null @@ -1,75 +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 . - */ -#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 deleted file mode 100644 index ffccc6e8e..000000000 --- a/stratosphere/memlet/source/memlet_service.cpp +++ /dev/null @@ -1,58 +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 . - */ -#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 deleted file mode 100644 index 6d003753e..000000000 --- a/stratosphere/memlet/source/memlet_service.hpp +++ /dev/null @@ -1,32 +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 . - */ -#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 deleted file mode 100644 index d6de42efc..000000000 --- a/stratosphere/memlet/system_module.mk +++ /dev/null @@ -1,131 +0,0 @@ -#--------------------------------------------------------------------------------- -# 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/ncm/source/ncm_main.cpp b/stratosphere/ncm/source/ncm_main.cpp index a5f1688cc..e1fe85c59 100644 --- a/stratosphere/ncm/source/ncm_main.cpp +++ b/stratosphere/ncm/source/ncm_main.cpp @@ -170,18 +170,16 @@ namespace ams { fs::SetAllocator(Allocate, Deallocate); fs::SetEnabledAutoAbort(false); - /* Initialize ncm api. */ - /* NOTE: Nintendo does this after initializing and starting threads. */ - ncm::InitializeWithObject(g_ncm_manager_service_object.GetShared()); - /* Create and initialize the content manager. */ R_ABORT_UNLESS(g_ncm_manager_service_object.GetImpl().Initialize(ManagerConfig)); - /* Initialize ncm's server and start threads. */ R_ABORT_UNLESS(g_ncm_server_manager.Initialize()); R_ABORT_UNLESS(g_ncm_server_manager.StartThreads()); + /* Initialize ncm api. */ + ncm::InitializeWithObject(g_ncm_manager_service_object.GetShared()); + /* Initialize lr's server and start threads. */ R_ABORT_UNLESS(g_lr_server_manager.Initialize()); R_ABORT_UNLESS(g_lr_server_manager.StartThreads()); diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index 4ffe5e94e..f999cdcc7 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -1,7 +1,7 @@ { "name": "ProcessManager", "title_id": "0x0100000000000003", - "main_thread_stack_size": "0x00003000", + "main_thread_stack_size": "0x00002000", "main_thread_priority": 49, "default_cpu_id": 3, "process_category": 1, @@ -85,7 +85,6 @@ "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 deleted file mode 100644 index b622be264..000000000 --- a/stratosphere/pm/source/impl/pm_process_attributes.hpp +++ /dev/null @@ -1,35 +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 . - */ -#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 d472803dc..a867cac5b 100644 --- a/stratosphere/pm/source/impl/pm_process_info.cpp +++ b/stratosphere/pm/source/impl/pm_process_info.cpp @@ -18,65 +18,7 @@ namespace ams::pm::impl { - namespace { - - template - class ProcessInfoAllocator { - NON_COPYABLE(ProcessInfoAllocator); - NON_MOVEABLE(ProcessInfoAllocator); - static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small."); - private: - util::TypedStorage m_process_info_storages[MaxProcessInfos]{}; - bool m_process_info_allocated[MaxProcessInfos]{}; - os::SdkMutex m_lock{}; - private: - constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const { - return process_info - GetPointer(m_process_info_storages[0]); - } - public: - constexpr ProcessInfoAllocator() = default; - - template - ProcessInfo *AllocateProcessInfo(Args &&... args) { - std::scoped_lock lk(m_lock); - - for (size_t i = 0; i < MaxProcessInfos; i++) { - if (!m_process_info_allocated[i]) { - m_process_info_allocated[i] = true; - - std::memset(m_process_info_storages + i, 0, sizeof(m_process_info_storages[i])); - - return util::ConstructAt(m_process_info_storages[i], std::forward(args)...); - } - } - - return nullptr; - } - - void FreeProcessInfo(ProcessInfo *process_info) { - std::scoped_lock lk(m_lock); - - const size_t index = this->GetProcessInfoIndex(process_info); - AMS_ABORT_UNLESS(index < MaxProcessInfos); - AMS_ABORT_UNLESS(m_process_info_allocated[index]); - - util::DestroyAt(m_process_info_storages[index]); - m_process_info_allocated[index] = false; - } - }; - - /* Process lists. */ - constinit ProcessList g_process_list; - constinit ProcessList g_exit_list; - - /* Process Info Allocation. */ - /* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */ - constexpr size_t MaxProcessCount = 0x60; - constinit ProcessInfoAllocator g_process_info_allocator; - - } - - 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) { + 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) { os::InitializeMultiWaitHolder(std::addressof(m_multi_wait_holder), m_handle); os::SetMultiWaitHolderUserData(std::addressof(m_multi_wait_holder), reinterpret_cast(this)); } @@ -95,27 +37,10 @@ namespace ams::pm::impl { /* Close the process's handle. */ os::CloseNativeHandle(m_handle); m_handle = os::InvalidNativeHandle; + + /* Unlink the process from its multi wait. */ + os::UnlinkMultiWaitHolder(std::addressof(m_multi_wait_holder)); } } - ProcessListAccessor GetProcessList() { - return ProcessListAccessor(g_process_list); - } - - ProcessListAccessor GetExitList() { - 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, 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) { - /* Remove the process from the list. */ - list->Remove(process_info); - - /* Delete the process. */ - g_process_info_allocator.FreeProcessInfo(process_info); - } - } diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index 66e64c436..f89403767 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -15,7 +15,6 @@ */ #pragma once #include "pm_process_manager.hpp" -#include "pm_process_attributes.hpp" namespace ams::pm::impl { @@ -47,7 +46,6 @@ 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) { @@ -62,12 +60,12 @@ 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, const ProcessAttributes &attrs); + ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s); ~ProcessInfo(); void Cleanup(); - os::MultiWaitHolderType *GetMultiWaitHolder() { - return std::addressof(m_multi_wait_holder); + void LinkToMultiWait(os::MultiWaitType &multi_wait) { + os::LinkMultiWaitHolder(std::addressof(multi_wait), std::addressof(m_multi_wait_holder)); } os::NativeHandle GetHandle() const { @@ -90,10 +88,6 @@ namespace ams::pm::impl { return m_status; } - const ProcessAttributes &GetProcessAttributes() const { - return m_attrs; - } - svc::ProcessState GetState() const { return m_state; } @@ -238,10 +232,4 @@ 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, 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 8a4d7ba16..db0648acc 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -15,9 +15,9 @@ */ #include #include "pm_process_manager.hpp" -#include "pm_process_tracker.hpp" +#include "pm_resource_manager.hpp" + #include "pm_process_info.hpp" -#include "pm_spec.hpp" namespace ams::pm::impl { @@ -29,7 +29,13 @@ namespace ams::pm::impl { HookType_Application = (1 << 1), }; - #define GET_FLAG_MASK(flag) (hos_version >= hos::Version_5_0_0 ? static_cast(LaunchFlags_##flag) : static_cast(LaunchFlagsDeprecated_##flag)) + struct LaunchProcessArgs { + os::ProcessId *out_process_id; + ncm::ProgramLocation location; + u32 flags; + }; + +#define GET_FLAG_MASK(flag) (hos_version >= hos::Version_5_0_0 ? static_cast(LaunchFlags_##flag) : static_cast(LaunchFlagsDeprecated_##flag)) inline bool ShouldSignalOnExit(u32 launch_flags) { const auto hos_version = hos::GetVersion(); @@ -64,26 +70,115 @@ namespace ams::pm::impl { return launch_flags & GET_FLAG_MASK(DisableAslr); } - #undef GET_FLAG_MASK +#undef GET_FLAG_MASK + + template + class ProcessInfoAllocator { + NON_COPYABLE(ProcessInfoAllocator); + NON_MOVEABLE(ProcessInfoAllocator); + static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small."); + private: + util::TypedStorage m_process_info_storages[MaxProcessInfos]{}; + bool m_process_info_allocated[MaxProcessInfos]{}; + os::SdkMutex m_lock{}; + private: + constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const { + return process_info - GetPointer(m_process_info_storages[0]); + } + public: + constexpr ProcessInfoAllocator() = default; + + template + ProcessInfo *AllocateProcessInfo(Args &&... args) { + std::scoped_lock lk(m_lock); + + for (size_t i = 0; i < MaxProcessInfos; i++) { + if (!m_process_info_allocated[i]) { + m_process_info_allocated[i] = true; + + std::memset(m_process_info_storages + i, 0, sizeof(m_process_info_storages[i])); + + return util::ConstructAt(m_process_info_storages[i], std::forward(args)...); + } + } + + return nullptr; + } + + void FreeProcessInfo(ProcessInfo *process_info) { + std::scoped_lock lk(m_lock); + + const size_t index = this->GetProcessInfoIndex(process_info); + AMS_ABORT_UNLESS(index < MaxProcessInfos); + AMS_ABORT_UNLESS(m_process_info_allocated[index]); + + util::DestroyAt(m_process_info_storages[index]); + m_process_info_allocated[index] = false; + } + }; /* Process Tracking globals. */ - constinit ProcessTracker g_process_tracker; - alignas(os::ThreadStackAlignment) constinit u8 g_process_track_thread_stack[8_KB]; + void ProcessTrackingMain(void *); + + constinit os::ThreadType g_process_track_thread; + alignas(os::ThreadStackAlignment) constinit u8 g_process_track_thread_stack[16_KB]; + + /* Process lists. */ + constinit ProcessList g_process_list; + constinit ProcessList g_dead_process_list; + + /* Process Info Allocation. */ + /* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */ + constexpr size_t MaxProcessCount = 0x60; + constinit ProcessInfoAllocator g_process_info_allocator; /* Global events. */ + constinit os::SystemEventType g_process_event; constinit os::SystemEventType g_hook_to_create_process_event; constinit os::SystemEventType g_hook_to_create_application_process_event; constinit os::SystemEventType g_boot_finished_event; + /* Process Launch synchronization globals. */ + constinit os::SdkMutex g_launch_program_lock; + os::Event g_process_launch_start_event(os::EventClearMode_AutoClear); + os::Event g_process_launch_finish_event(os::EventClearMode_AutoClear); + constinit Result g_process_launch_result = ResultSuccess(); + constinit LaunchProcessArgs g_process_launch_args = {}; + /* Hook globals. */ constinit std::atomic g_program_id_hook; constinit std::atomic g_application_hook; + /* Forward declarations. */ + Result LaunchProcess(os::MultiWaitType &multi_wait, const LaunchProcessArgs &args); + void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info); + /* Helpers. */ - void CreateDebuggerEvent() { - /* Create debugger hook events. */ - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_process_event), os::EventClearMode_AutoClear, true)); - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true)); + void ProcessTrackingMain(void *) { + /* This is the main loop of the process tracking thread. */ + + /* Setup multi wait/holders. */ + os::MultiWaitType process_multi_wait; + os::MultiWaitHolderType start_event_holder; + os::InitializeMultiWait(std::addressof(process_multi_wait)); + os::InitializeMultiWaitHolder(std::addressof(start_event_holder), g_process_launch_start_event.GetBase()); + os::LinkMultiWaitHolder(std::addressof(process_multi_wait), std::addressof(start_event_holder)); + + while (true) { + auto signaled_holder = os::WaitAny(std::addressof(process_multi_wait)); + if (signaled_holder == std::addressof(start_event_holder)) { + /* Launch start event signaled. */ + /* TryWait will clear signaled, preventing duplicate notifications. */ + if (g_process_launch_start_event.TryWait()) { + g_process_launch_result = LaunchProcess(process_multi_wait, g_process_launch_args); + g_process_launch_finish_event.Signal(); + } + } else { + /* Some process was signaled. */ + ProcessListAccessor list(g_process_list); + OnProcessSignaled(list, reinterpret_cast(os::GetMultiWaitHolderUserData(signaled_holder))); + } + } } inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) { @@ -100,7 +195,7 @@ namespace ams::pm::impl { } bool HasApplicationProcess() { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); for (auto &process : *list) { if (process.IsApplication()) { @@ -117,14 +212,19 @@ namespace ams::pm::impl { R_SUCCEED(); } - 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; + void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { + /* Remove the process from the list. */ + list->Remove(process_info); + /* Delete the process. */ + g_process_info_allocator.FreeProcessInfo(process_info); + } + + Result LaunchProcess(os::MultiWaitType &multi_wait, const LaunchProcessArgs &args) { /* 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, attrs.program_attrs)); + R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), args.location)); 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; @@ -132,14 +232,14 @@ namespace ams::pm::impl { R_UNLESS(!is_application || !HasApplicationProcess(), pm::ResultApplicationRunning()); /* Fix the program location to use the right program id. */ - const ncm::ProgramLocation fixed_location = ncm::ProgramLocation::Make(program_info.program_id, static_cast(loc.storage_id)); + const ncm::ProgramLocation location = ncm::ProgramLocation::Make(program_info.program_id, static_cast(args.location.storage_id)); /* Pin and create the process. */ os::NativeHandle process_handle; ldr::PinId pin_id; { /* Pin the program with loader. */ - R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), fixed_location, override_status)); + R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), location, override_status)); /* If we fail after now, unpin. */ ON_RESULT_FAILURE { ldr::pm::UnpinProgram(pin_id); }; @@ -163,28 +263,29 @@ namespace ams::pm::impl { ON_RESULT_FAILURE_2 { if (mitm_boost_size > 0 || is_application) { R_ABORT_UNLESS(BoostSystemMemoryResourceLimitForMitm(0)); } }; /* Ensure resources are available. */ - WaitResourceAvailable(std::addressof(program_info)); + resource::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)), attrs.program_attrs)); + R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(args.flags), resource::GetResourceLimitHandle(std::addressof(program_info)))); } /* 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, attrs); + ProcessInfo *process_info = g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status); AMS_ABORT_UNLESS(process_info != nullptr); - /* Add the new process info to the process list. */ + /* Link new process info. */ { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); list->push_back(*process_info); + process_info->LinkToMultiWait(multi_wait); } /* Prevent resource leakage if register fails. */ ON_RESULT_FAILURE { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); process_info->Cleanup(); CleanupProcessInfo(list, process_info); }; @@ -195,85 +296,178 @@ 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, 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)); + R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(location.program_id), static_cast(location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size)); + R_TRY(sm::manager::RegisterProcess(process_id, location.program_id, override_status, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size)); /* Set flags. */ if (is_application) { process_info->SetApplication(); } - if (ShouldSignalOnStart(flags) && allow_debug) { + if (ShouldSignalOnStart(args.flags) && allow_debug) { process_info->SetSignalOnStart(); } - if (ShouldSignalOnExit(flags)) { + if (ShouldSignalOnExit(args.flags)) { process_info->SetSignalOnExit(); } - if (ShouldSignalOnDebugEvent(flags) && allow_debug) { + if (ShouldSignalOnDebugEvent(args.flags) && allow_debug) { process_info->SetSignalOnDebugEvent(); } /* Process hooks/signaling. */ - if (fixed_location.program_id == g_program_id_hook) { + if (location.program_id == g_program_id_hook) { os::SignalSystemEvent(std::addressof(g_hook_to_create_process_event)); g_program_id_hook = ncm::InvalidProgramId; } else if (is_application && g_application_hook) { os::SignalSystemEvent(std::addressof(g_hook_to_create_application_process_event)); g_application_hook = false; - } else if (!ShouldStartSuspended(flags)) { + } else if (!ShouldStartSuspended(args.flags)) { R_TRY(StartProcess(process_info, std::addressof(program_info))); } - *out_process_id = process_id; - *out_process_info = process_info; + *args.out_process_id = process_id; R_SUCCEED(); } + void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info) { + /* Reset the process's signal. */ + svc::ResetSignal(process_info->GetHandle()); + + /* Update the process's state. */ + const svc::ProcessState old_state = process_info->GetState(); + { + s64 tmp = 0; + R_ABORT_UNLESS(svc::GetProcessInfo(std::addressof(tmp), process_info->GetHandle(), svc::ProcessInfoType_ProcessState)); + process_info->SetState(static_cast(tmp)); + } + const svc::ProcessState new_state = process_info->GetState(); + + /* If we're transitioning away from crashed, clear waiting attached. */ + if (old_state == svc::ProcessState_Crashed && new_state != svc::ProcessState_Crashed) { + process_info->ClearExceptionWaitingAttach(); + } + + switch (new_state) { + case svc::ProcessState_Created: + case svc::ProcessState_CreatedAttached: + case svc::ProcessState_Terminating: + break; + case svc::ProcessState_Running: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->ClearSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } else if (hos::GetVersion() >= hos::Version_2_0_0 && process_info->ShouldSignalOnStart()) { + process_info->SetStartedStateChanged(); + process_info->ClearSignalOnStart(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->ClearUnhandledException(); + break; + case svc::ProcessState_Crashed: + if (!process_info->HasUnhandledException()) { + process_info->SetExceptionOccurred(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->SetExceptionWaitingAttach(); + break; + case svc::ProcessState_RunningAttached: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->ClearSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->ClearUnhandledException(); + break; + case svc::ProcessState_Terminated: + /* Free process resources, unlink from multi wait. */ + process_info->Cleanup(); + + if (hos::GetVersion() < hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { + os::SignalSystemEvent(std::addressof(g_process_event)); + } else { + /* Handle the case where we need to keep the process alive some time longer. */ + if (hos::GetVersion() >= hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { + /* Remove from the living list. */ + list->Remove(process_info); + + /* Add the process to the list of dead processes. */ + { + ProcessListAccessor dead_list(g_dead_process_list); + dead_list->push_back(*process_info); + } + + /* Signal. */ + os::SignalSystemEvent(std::addressof(g_process_event)); + } else { + /* Actually delete process. */ + CleanupProcessInfo(list, process_info); + } + } + break; + case svc::ProcessState_DebugBreak: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->SetSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + break; + } + } + } /* Initialization. */ Result InitializeProcessManager() { /* Create events. */ - CreateProcessEvent(); - CreateDebuggerEvent(); - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_boot_finished_event), os::EventClearMode_AutoClear, true)); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_process_event), os::EventClearMode_AutoClear, true)); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_process_event), os::EventClearMode_AutoClear, true)); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true)); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_boot_finished_event), os::EventClearMode_AutoClear, true)); /* Initialize resource limits. */ - R_TRY(InitializeSpec()); + R_TRY(resource::InitializeResourceManager()); - /* Initialize the process tracker. */ - g_process_tracker.Initialize(g_process_track_thread_stack, sizeof(g_process_track_thread_stack)); + /* Create thread. */ + R_ABORT_UNLESS(os::CreateThread(std::addressof(g_process_track_thread), ProcessTrackingMain, nullptr, g_process_track_thread_stack, sizeof(g_process_track_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(pm, ProcessTrack))); + os::SetThreadNamePointer(std::addressof(g_process_track_thread), AMS_GET_SYSTEM_THREAD_NAME(pm, ProcessTrack)); - /* Start the process tracker thread. */ - g_process_tracker.StartThread(); + /* Start thread. */ + os::StartThread(std::addressof(g_process_track_thread)); R_SUCCEED(); } /* Process Management. */ 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, ProcessAttributes_Nx)); + /* Ensure we only try to launch one program at a time. */ + std::scoped_lock lk(g_launch_program_lock); - /* Register the process info with the tracker. */ - g_process_tracker.QueueEntry(process_info); - R_SUCCEED(); + /* Set global arguments, signal, wait. */ + g_process_launch_args = { + .out_process_id = out_process_id, + .location = loc, + .flags = flags, + }; + g_process_launch_start_event.Signal(); + g_process_launch_finish_event.Wait(); + + R_RETURN(g_process_launch_result); } Result StartProcess(os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); R_UNLESS(!process_info->HasStarted(), pm::ResultAlreadyStarted()); ldr::ProgramInfo program_info; - R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation(), process_info->GetProcessAttributes().program_attrs)); + R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation())); R_RETURN(StartProcess(process_info, std::addressof(program_info))); } Result TerminateProcess(os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -282,7 +476,7 @@ namespace ams::pm::impl { } Result TerminateProgram(ncm::ProgramId program_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(program_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -290,10 +484,15 @@ namespace ams::pm::impl { R_RETURN(svc::TerminateProcess(process_info->GetHandle())); } + Result GetProcessEventHandle(os::NativeHandle *out) { + *out = os::GetReadableHandleOfSystemEvent(std::addressof(g_process_event)); + R_SUCCEED(); + } + Result GetProcessEventInfo(ProcessEventInfo *out) { /* Check for event from current process. */ { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); for (auto &process : *list) { @@ -329,14 +528,14 @@ namespace ams::pm::impl { /* Check for event from exited process. */ if (hos::GetVersion() >= hos::Version_5_0_0) { - auto exit_list = GetExitList(); + ProcessListAccessor dead_list(g_dead_process_list); - if (!exit_list->empty()) { - auto &process_info = exit_list->front(); - out->event = GetProcessEventValue(ProcessEvent::Exited); + if (!dead_list->empty()) { + auto &process_info = dead_list->front(); + out->event = GetProcessEventValue(ProcessEvent::Exited); out->process_id = process_info.GetProcessId(); - CleanupProcessInfo(exit_list, std::addressof(process_info)); + CleanupProcessInfo(dead_list, std::addressof(process_info)); R_SUCCEED(); } } @@ -347,7 +546,7 @@ namespace ams::pm::impl { } Result CleanupProcess(os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -358,7 +557,7 @@ namespace ams::pm::impl { } Result ClearExceptionOccurred(os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -376,7 +575,7 @@ namespace ams::pm::impl { } Result GetExceptionProcessIdList(u32 *out_count, os::ProcessId *out_process_ids, size_t max_out_count) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); size_t count = 0; @@ -397,7 +596,7 @@ namespace ams::pm::impl { } Result GetProcessId(os::ProcessId *out, ncm::ProgramId program_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(program_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -407,7 +606,7 @@ namespace ams::pm::impl { } Result GetProgramId(ncm::ProgramId *out, os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -417,7 +616,7 @@ namespace ams::pm::impl { } Result GetApplicationProcessId(os::ProcessId *out_process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); for (auto &process : *list) { if (process.IsApplication()) { @@ -430,7 +629,7 @@ namespace ams::pm::impl { } Result AtmosphereGetProcessInfo(os::NativeHandle *out_process_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { - auto list = GetProcessList(); + ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -507,4 +706,33 @@ namespace ams::pm::impl { R_SUCCEED(); } + /* Resource Limit API. */ + Result BoostSystemMemoryResourceLimit(u64 boost_size) { + R_RETURN(resource::BoostSystemMemoryResourceLimit(boost_size)); + } + + Result BoostApplicationThreadResourceLimit() { + R_RETURN(resource::BoostApplicationThreadResourceLimit()); + } + + Result BoostSystemThreadResourceLimit() { + R_RETURN(resource::BoostSystemThreadResourceLimit()); + } + + Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out) { + R_RETURN(resource::GetCurrentResourceLimitValues(ResourceLimitGroup_Applet, out)); + } + + Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out) { + R_RETURN(resource::GetPeakResourceLimitValues(ResourceLimitGroup_Applet, out)); + } + + Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource) { + R_RETURN(resource::GetResourceLimitValues(out_cur_val, out_lim_val, static_cast(group), static_cast(resource))); + } + + Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size) { + R_RETURN(resource::BoostSystemMemoryResourceLimitForMitm(boost_size)); + } + } diff --git a/stratosphere/pm/source/impl/pm_process_manager.hpp b/stratosphere/pm/source/impl/pm_process_manager.hpp index 61acbe1b0..83ccc7a85 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.hpp +++ b/stratosphere/pm/source/impl/pm_process_manager.hpp @@ -48,4 +48,13 @@ namespace ams::pm::impl { Result NotifyBootFinished(); Result GetBootFinishedEventHandle(os::NativeHandle *out); + /* Resource Limit API. */ + Result BoostSystemMemoryResourceLimit(u64 boost_size); + Result BoostApplicationThreadResourceLimit(); + Result BoostSystemThreadResourceLimit(); + Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out); + Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out); + Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource); + Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size); + } diff --git a/stratosphere/pm/source/impl/pm_process_tracker.cpp b/stratosphere/pm/source/impl/pm_process_tracker.cpp deleted file mode 100644 index 5d1c3b418..000000000 --- a/stratosphere/pm/source/impl/pm_process_tracker.cpp +++ /dev/null @@ -1,193 +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 . - */ -#include -#include "pm_process_tracker.hpp" -#include "pm_process_info.hpp" -#include "pm_spec.hpp" - -namespace ams::pm::impl { - - namespace { - - /* Global process event. */ - constinit os::SystemEventType g_process_event; - - } - - void ProcessTracker::Initialize(void *stack, size_t stack_size) { - /* Initialize our events. */ - os::InitializeEvent(std::addressof(m_request_event), false, os::EventClearMode_AutoClear); - os::InitializeEvent(std::addressof(m_reply_event), false, os::EventClearMode_AutoClear); - - /* Our process count should initially be zero. */ - m_process_count = 0; - - /* Create the process tracking thread. */ - R_ABORT_UNLESS(os::CreateThread(std::addressof(m_thread), ProcessTracker::ThreadFunction, this, stack, stack_size, AMS_GET_SYSTEM_THREAD_PRIORITY(pm, ProcessTrack))); - os::SetThreadNamePointer(std::addressof(m_thread), AMS_GET_SYSTEM_THREAD_NAME(pm, ProcessTrack)); - } - - void ProcessTracker::StartThread() { - /* Start thread. */ - os::StartThread(std::addressof(m_thread)); - } - - void ProcessTracker::ThreadBody() { - /* This is the main loop of the process tracking thread. */ - - /* Setup multi wait/holders. */ - os::MultiWaitType process_multi_wait; - os::MultiWaitHolderType enqueue_event_holder; - os::InitializeMultiWait(std::addressof(process_multi_wait)); - os::InitializeMultiWaitHolder(std::addressof(enqueue_event_holder), std::addressof(m_request_event)); - os::LinkMultiWaitHolder(std::addressof(process_multi_wait), std::addressof(enqueue_event_holder)); - - while (true) { - auto signaled_holder = os::WaitAny(std::addressof(process_multi_wait)); - if (signaled_holder == std::addressof(enqueue_event_holder)) { - /* TryWait will clear signaled, preventing duplicate notifications. */ - if (os::TryWaitEvent(std::addressof(m_request_event))) { - /* Link the process to our multi-wait. */ - os::LinkMultiWaitHolder(std::addressof(process_multi_wait), m_queued_process_info->GetMultiWaitHolder()); - m_queued_process_info = nullptr; - - /* Increment our process count. */ - ++m_process_count; - - /* Reply. */ - os::SignalEvent(std::addressof(m_reply_event)); - } - } else { - /* Some process was signaled. */ - this->OnProcessSignaled(reinterpret_cast(os::GetMultiWaitHolderUserData(signaled_holder))); - } - } - } - - void ProcessTracker::QueueEntry(ProcessInfo *process_info) { - /* Lock ourselves. */ - std::scoped_lock lk(m_mutex); - - /* Request to enqueue the process info. */ - m_queued_process_info = process_info; - os::SignalEvent(std::addressof(m_request_event)); - - /* Wait for acknowledgement. */ - os::WaitEvent(std::addressof(m_reply_event)); - } - - void ProcessTracker::OnProcessSignaled(ProcessInfo *process_info) { - /* Get the process list. */ - auto list = GetProcessList(); - - /* Reset the process's signal. */ - svc::ResetSignal(process_info->GetHandle()); - - /* Update the process's state. */ - const svc::ProcessState old_state = process_info->GetState(); - { - s64 tmp = 0; - R_ABORT_UNLESS(svc::GetProcessInfo(std::addressof(tmp), process_info->GetHandle(), svc::ProcessInfoType_ProcessState)); - process_info->SetState(static_cast(tmp)); - } - const svc::ProcessState new_state = process_info->GetState(); - - /* If we're transitioning away from crashed, clear waiting attached. */ - if (old_state == svc::ProcessState_Crashed && new_state != svc::ProcessState_Crashed) { - process_info->ClearExceptionWaitingAttach(); - } - - switch (new_state) { - case svc::ProcessState_Created: - case svc::ProcessState_CreatedAttached: - case svc::ProcessState_Terminating: - break; - case svc::ProcessState_Running: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->ClearSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } else if (hos::GetVersion() >= hos::Version_2_0_0 && process_info->ShouldSignalOnStart()) { - process_info->SetStartedStateChanged(); - process_info->ClearSignalOnStart(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->ClearUnhandledException(); - break; - case svc::ProcessState_Crashed: - if (!process_info->HasUnhandledException()) { - process_info->SetExceptionOccurred(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->SetExceptionWaitingAttach(); - break; - case svc::ProcessState_RunningAttached: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->ClearSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->ClearUnhandledException(); - break; - case svc::ProcessState_Terminated: - /* Unlink from multi wait. */ - os::UnlinkMultiWaitHolder(process_info->GetMultiWaitHolder()); - - /* Free process resources. */ - process_info->Cleanup(); - - if (hos::GetVersion() < hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { - os::SignalSystemEvent(std::addressof(g_process_event)); - } else { - /* Handle the case where we need to keep the process alive some time longer. */ - if (hos::GetVersion() >= hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { - /* Remove from the living list. */ - list->Remove(process_info); - - /* Add the process to the list of dead processes. */ - { - GetExitList()->push_back(*process_info); - } - - /* Signal. */ - os::SignalSystemEvent(std::addressof(g_process_event)); - } else { - /* Actually delete process. */ - CleanupProcessInfo(list, process_info); - } - } - break; - case svc::ProcessState_DebugBreak: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->SetSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - break; - } - } - - void CreateProcessEvent() { - /* Create process event. */ - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_process_event), os::EventClearMode_AutoClear, true)); - } - - Result GetProcessEventHandle(os::NativeHandle *out) { - *out = os::GetReadableHandleOfSystemEvent(std::addressof(g_process_event)); - R_SUCCEED(); - } - -} diff --git a/stratosphere/pm/source/impl/pm_process_tracker.hpp b/stratosphere/pm/source/impl/pm_process_tracker.hpp deleted file mode 100644 index c1de7c2aa..000000000 --- a/stratosphere/pm/source/impl/pm_process_tracker.hpp +++ /dev/null @@ -1,57 +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 . - */ -#pragma once -#include -#include "pm_process_info.hpp" - -namespace ams::pm::impl { - - class ProcessTracker { - NON_COPYABLE(ProcessTracker); - NON_MOVEABLE(ProcessTracker); - private: - os::ThreadType m_thread; - os::EventType m_request_event; - os::EventType m_reply_event; - os::SdkMutex m_mutex; - ProcessInfo *m_queued_process_info; - util::Atomic m_process_count; - public: - constexpr ProcessTracker() : m_thread(), m_request_event(), m_reply_event(), m_mutex(), m_queued_process_info(nullptr), m_process_count(0) { - /* ... */ - } - - void Initialize(void *stack, size_t stack_size); - void StartThread(); - - void QueueEntry(ProcessInfo *process_info); - - u32 GetProcessCount() const { - return m_process_count; - } - private: - void OnProcessSignaled(ProcessInfo *process_info); - private: - static void ThreadFunction(void *_this) { - static_cast(_this)->ThreadBody(); - } - - void ThreadBody(); - }; - - void CreateProcessEvent(); - -} diff --git a/stratosphere/pm/source/impl/pm_spec.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp similarity index 89% rename from stratosphere/pm/source/impl/pm_spec.cpp rename to stratosphere/pm/source/impl/pm_resource_manager.cpp index ee0e38060..6c5805b5d 100644 --- a/stratosphere/pm/source/impl/pm_spec.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -14,9 +14,9 @@ * along with this program. If not, see . */ #include -#include "pm_spec.hpp" +#include "pm_resource_manager.hpp" -namespace ams::pm::impl { +namespace ams::pm::resource { namespace { @@ -82,7 +82,7 @@ namespace ams::pm::impl { [svc::LimitableResource_ThreadCountMax] = BaseAppletThreads, [svc::LimitableResource_EventCountMax] = 0, [svc::LimitableResource_TransferMemoryCountMax] = 32, - [svc::LimitableResource_SessionCountMax] = 5 + 1, /* Add a session for atmosphere's memlet system module. */ + [svc::LimitableResource_SessionCountMax] = 5, }, }; @@ -170,18 +170,10 @@ namespace ams::pm::impl { } void WaitApplicationMemoryAvailable() { - /* Get firmware version. */ - const auto fw_ver = hos::GetVersion(); - - /* On 15.0.0+, pm considers application memory to be available if there is exactly 96 MB outstanding. */ - /* This is probably because this corresponds to the gameplay-recording memory. */ - constexpr u64 AllowedUsedApplicationMemory = 96_MB; - - /* Wait for memory to be available. */ u64 value = 0; while (true) { R_ABORT_UNLESS(svc::GetSystemInfo(&value, svc::SystemInfoType_UsedPhysicalMemorySize, svc::InvalidHandle, svc::PhysicalMemorySystemInfo_Application)); - if (value == 0 || (fw_ver >= hos::Version_15_0_0 && value == AllowedUsedApplicationMemory)) { + if (value == 0) { break; } os::SleepThread(TimeSpan::FromMilliSeconds(1)); @@ -209,8 +201,8 @@ namespace ams::pm::impl { R_SUCCEED(); } - template - ALWAYS_INLINE Result GetResourceLimitValueImpl(pm::ResourceLimitValue *out, ResourceLimitGroup group) { + template + ALWAYS_INLINE Result GetResourceLimitValuesImpl(ResourceLimitGroup group, pm::ResourceLimitValues *out) { /* Sanity check group. */ AMS_ABORT_UNLESS(group < ResourceLimitGroup_Count); @@ -219,11 +211,11 @@ namespace ams::pm::impl { /* Get values. */ int64_t values[svc::LimitableResource_Count]; - R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_PhysicalMemoryMax]), handle, svc::LimitableResource_PhysicalMemoryMax)); - R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_ThreadCountMax]), handle, svc::LimitableResource_ThreadCountMax)); - R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_EventCountMax]), handle, svc::LimitableResource_EventCountMax)); - R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_TransferMemoryCountMax]), handle, svc::LimitableResource_TransferMemoryCountMax)); - R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_SessionCountMax]), handle, svc::LimitableResource_SessionCountMax)); + R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_PhysicalMemoryMax]), handle, svc::LimitableResource_PhysicalMemoryMax)); + R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_ThreadCountMax]), handle, svc::LimitableResource_ThreadCountMax)); + R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_EventCountMax]), handle, svc::LimitableResource_EventCountMax)); + R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_TransferMemoryCountMax]), handle, svc::LimitableResource_TransferMemoryCountMax)); + R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_SessionCountMax]), handle, svc::LimitableResource_SessionCountMax)); /* Set to output. */ out->physical_memory = values[svc::LimitableResource_PhysicalMemoryMax]; @@ -243,35 +235,29 @@ namespace ams::pm::impl { const u64 boost_size = normal_boost + mitm_boost; /* Don't allow all application memory to be taken away. */ - R_UNLESS(boost_size < g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize()); + R_UNLESS(boost_size <= g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize()); const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size; { std::scoped_lock lk(g_resource_limit_lock); - const auto cur_boost_size = GetCurrentSystemMemoryBoostSize(); - if (hos::GetVersion() >= hos::Version_5_0_0) { /* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */ - if (boost_size < cur_boost_size) { + if (boost_size < GetCurrentSystemMemoryBoostSize()) { R_TRY(svc::SetUnsafeLimit(boost_size)); R_ABORT_UNLESS(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); - } else if (boost_size > cur_boost_size) { + } else { R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); R_ABORT_UNLESS(svc::SetUnsafeLimit(boost_size)); - } else { - /* If the boost size is equal, there's nothing to do. */ } } else { const u64 new_sys_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_System] + boost_size; - if (boost_size < cur_boost_size) { + if (boost_size < GetCurrentSystemMemoryBoostSize()) { R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); - } else if (boost_size > cur_boost_size) { - R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); - R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); } else { - /* If the boost size is equal, there's nothing to do. */ + R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); + R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); } } @@ -284,7 +270,8 @@ namespace ams::pm::impl { } - Result InitializeSpec() { + /* Resource API. */ + Result InitializeResourceManager() { /* Create resource limit handles. */ for (size_t i = 0; i < ResourceLimitGroup_Count; i++) { if (i == ResourceLimitGroup_System) { @@ -464,16 +451,16 @@ namespace ams::pm::impl { } } - Result GetResourceLimitCurrentValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { - R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitCurrentValue>(out, group)); + Result GetCurrentResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitCurrentValue>(group, out)); } - Result GetResourceLimitPeakValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { - R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitPeakValue>(out, group)); + Result GetPeakResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitPeakValue>(group, out)); } - Result GetResourceLimitLimitValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { - R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitLimitValue>(out, group)); + Result GetLimitResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitLimitValue>(group, out)); } Result GetResourceLimitValues(s64 *out_cur, s64 *out_lim, ResourceLimitGroup group, svc::LimitableResource resource) { diff --git a/stratosphere/pm/source/impl/pm_spec.hpp b/stratosphere/pm/source/impl/pm_resource_manager.hpp similarity index 76% rename from stratosphere/pm/source/impl/pm_spec.hpp rename to stratosphere/pm/source/impl/pm_resource_manager.hpp index 1f49282f4..029458203 100644 --- a/stratosphere/pm/source/impl/pm_spec.hpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.hpp @@ -16,10 +16,10 @@ #pragma once #include -namespace ams::pm::impl { - - Result InitializeSpec(); +namespace ams::pm::resource { + /* Resource API. */ + Result InitializeResourceManager(); Result BoostSystemMemoryResourceLimit(u64 boost_size); Result BoostApplicationThreadResourceLimit(); Result BoostSystemThreadResourceLimit(); @@ -31,9 +31,9 @@ namespace ams::pm::impl { void WaitResourceAvailable(const ldr::ProgramInfo *info); - Result GetResourceLimitCurrentValue(pm::ResourceLimitValue *out, ResourceLimitGroup group); - Result GetResourceLimitPeakValue(pm::ResourceLimitValue *outm, ResourceLimitGroup group); - Result GetResourceLimitLimitValue(pm::ResourceLimitValue *out, ResourceLimitGroup group); + Result GetCurrentResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); + Result GetPeakResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); + Result GetLimitResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); Result GetResourceLimitValues(s64 *out_cur, s64 *out_lim, ResourceLimitGroup group, svc::LimitableResource resource); diff --git a/stratosphere/pm/source/pm_boot_mode_service.cpp b/stratosphere/pm/source/pm_boot_mode_service.cpp index a1a762d34..719fff51f 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.cpp +++ b/stratosphere/pm/source/pm_boot_mode_service.cpp @@ -21,8 +21,7 @@ namespace ams::pm { namespace { /* Global bootmode. */ - constinit BootMode g_boot_mode = BootMode::Normal; - constinit u32 g_unknown = 0; + BootMode g_boot_mode = BootMode::Normal; } @@ -48,14 +47,4 @@ 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 b47536ed7..c650e9b47 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.hpp +++ b/stratosphere/pm/source/pm_boot_mode_service.hpp @@ -22,8 +22,6 @@ 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_debug_monitor_service.cpp b/stratosphere/pm/source/pm_debug_monitor_service.cpp index d9c3b1621..dd5433c78 100644 --- a/stratosphere/pm/source/pm_debug_monitor_service.cpp +++ b/stratosphere/pm/source/pm_debug_monitor_service.cpp @@ -16,7 +16,6 @@ #include #include "pm_debug_monitor_service.hpp" #include "impl/pm_process_manager.hpp" -#include "impl/pm_spec.hpp" namespace ams::pm { @@ -77,7 +76,7 @@ namespace ams::pm { } Result DebugMonitorService::AtmosphereGetCurrentLimitInfo(sf::Out out_cur_val, sf::Out out_lim_val, u32 group, u32 resource) { - R_RETURN(impl::GetResourceLimitValues(out_cur_val.GetPointer(), out_lim_val.GetPointer(), static_cast(group), static_cast(resource))); + R_RETURN(impl::AtmosphereGetCurrentLimitInfo(out_cur_val.GetPointer(), out_lim_val.GetPointer(), group, resource)); } } diff --git a/stratosphere/pm/source/pm_info_service.cpp b/stratosphere/pm/source/pm_info_service.cpp index 29ae868cb..26c7f2781 100644 --- a/stratosphere/pm/source/pm_info_service.cpp +++ b/stratosphere/pm/source/pm_info_service.cpp @@ -16,7 +16,6 @@ #include #include "pm_info_service.hpp" #include "impl/pm_process_manager.hpp" -#include "impl/pm_spec.hpp" namespace ams::pm { @@ -34,12 +33,12 @@ namespace ams::pm { R_RETURN(impl::GetProgramId(out.GetPointer(), process_id)); } - Result InformationService::GetAppletResourceLimitCurrentValue(sf::Out out) { - R_RETURN(impl::GetResourceLimitCurrentValue(out.GetPointer(), ResourceLimitGroup_Applet)); + Result InformationService::GetAppletCurrentResourceLimitValues(sf::Out out) { + R_RETURN(impl::GetAppletCurrentResourceLimitValues(out.GetPointer())); } - Result InformationService::GetAppletResourceLimitPeakValue(sf::Out out) { - R_RETURN(impl::GetResourceLimitPeakValue(out.GetPointer(), ResourceLimitGroup_Applet)); + Result InformationService::GetAppletPeakResourceLimitValues(sf::Out out) { + R_RETURN(impl::GetAppletPeakResourceLimitValues(out.GetPointer())); } /* Atmosphere extension commands. */ diff --git a/stratosphere/pm/source/pm_info_service.hpp b/stratosphere/pm/source/pm_info_service.hpp index 1fd892542..1f8010f11 100644 --- a/stratosphere/pm/source/pm_info_service.hpp +++ b/stratosphere/pm/source/pm_info_service.hpp @@ -22,8 +22,8 @@ namespace ams::pm { public: /* Actual command implementations. */ Result GetProgramId(sf::Out out, os::ProcessId process_id); - Result GetAppletResourceLimitCurrentValue(sf::Out out); - Result GetAppletResourceLimitPeakValue(sf::Out out); + Result GetAppletCurrentResourceLimitValues(sf::Out out); + Result GetAppletPeakResourceLimitValues(sf::Out out); /* Atmosphere extension commands. */ Result AtmosphereGetProcessId(sf::Out out, ncm::ProgramId program_id); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 5bef871c7..b7d775be9 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), 0); + fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl)); sm::manager::UnregisterProcess(process_id); sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); } diff --git a/stratosphere/pm/source/pm_shell_service.cpp b/stratosphere/pm/source/pm_shell_service.cpp index db69c6f12..7248bc0e2 100644 --- a/stratosphere/pm/source/pm_shell_service.cpp +++ b/stratosphere/pm/source/pm_shell_service.cpp @@ -16,7 +16,6 @@ #include #include "pm_shell_service.hpp" #include "impl/pm_process_manager.hpp" -#include "impl/pm_spec.hpp" namespace ams::pm { diff --git a/stratosphere/ro/source/impl/ro_nro_utils.cpp b/stratosphere/ro/source/impl/ro_nro_utils.cpp index 3f01a1c99..588a26387 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.cpp @@ -51,15 +51,11 @@ namespace ams::ro::impl { R_SUCCEED(); } - 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; + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) { + const u64 rx_offset = 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 9ea2f7b32..df018c872 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, bool is_aligned_header); + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size); 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 0eee275eb..0be672f37 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, bool *out_aligned_header, 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, 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,7 +306,6 @@ 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(); } @@ -558,11 +557,10 @@ namespace ams::ro::impl { /* Validate the NRO (parsing region extents). */ u64 rx_size = 0, ro_size = 0, rw_size = 0; - 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)); + 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)); /* Set NRO perms. */ - R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size, aligned_header)); + R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size)); context->SetNroInfoInUse(nro_info, true); nro_info->code_size = rx_size + ro_size; diff --git a/stratosphere/sm/source/impl/sm_service_manager.cpp b/stratosphere/sm/source/impl/sm_service_manager.cpp index a645d5340..2007ac740 100644 --- a/stratosphere/sm/source/impl/sm_service_manager.cpp +++ b/stratosphere/sm/source/impl/sm_service_manager.cpp @@ -437,7 +437,7 @@ namespace ams::sm::impl { { /* TODO: Convert mitm internal messaging to use tipc? */ ::Service srv { .session = mitm_info->query_h }; - R_ABORT_UNLESS((serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm))); + R_ABORT_UNLESS(::serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm)); } /* If we shouldn't mitm, give normal session. */ diff --git a/stratosphere/spl/source/spl_es_service.hpp b/stratosphere/spl/source/spl_es_service.hpp index 57943ec24..a4cba97f6 100644 --- a/stratosphere/spl/source/spl_es_service.hpp +++ b/stratosphere/spl/source/spl_es_service.hpp @@ -55,10 +55,6 @@ namespace ams::spl { Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key) { R_RETURN(m_manager.LoadPreparedAesKey(keyslot, this, access_key)); } - - Result PrepareEsUnknown2Key(sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) { - R_RETURN(m_manager.PrepareEsUnknown2Key(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation)); - } }; static_assert(spl::impl::IsIEsInterface); diff --git a/stratosphere/spl/source/spl_secure_monitor_manager.cpp b/stratosphere/spl/source/spl_secure_monitor_manager.cpp index c31bae8bf..e5b899169 100644 --- a/stratosphere/spl/source/spl_secure_monitor_manager.cpp +++ b/stratosphere/spl/source/spl_secure_monitor_manager.cpp @@ -121,10 +121,6 @@ namespace ams::spl { R_RETURN(impl::PrepareEsArchiveKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation)); } - Result SecureMonitorManager::PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) { - R_RETURN(impl::PrepareEsUnknown2Key(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation)); - } - Result SecureMonitorManager::PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) { R_RETURN(impl::PrepareCommonEsTitleKey(out_access_key, key_source, generation)); } diff --git a/stratosphere/spl/source/spl_secure_monitor_manager.hpp b/stratosphere/spl/source/spl_secure_monitor_manager.hpp index c01311ef3..f54ff5da0 100644 --- a/stratosphere/spl/source/spl_secure_monitor_manager.hpp +++ b/stratosphere/spl/source/spl_secure_monitor_manager.hpp @@ -52,7 +52,6 @@ namespace ams::spl { Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option); Result PrepareEsTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); - Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation); Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key); Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner); diff --git a/stratosphere/stratosphere.mk b/stratosphere/stratosphere.mk index b20244ec6..5b06a6d98 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 memlet +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: $(ALL_MODULES) diff --git a/troposphere/daybreak/Makefile b/troposphere/daybreak/Makefile index adb6339f1..f93397c1d 100644 --- a/troposphere/daybreak/Makefile +++ b/troposphere/daybreak/Makefile @@ -61,7 +61,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ -CXXFLAGS := $(CFLAGS) -std=gnu++23 -fno-exceptions -fno-rtti +CXXFLAGS := $(CFLAGS) -std=gnu++20 -fno-exceptions -fno-rtti ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) diff --git a/troposphere/haze/Makefile b/troposphere/haze/Makefile index e1e29949c..f80a28a07 100644 --- a/troposphere/haze/Makefile +++ b/troposphere/haze/Makefile @@ -42,10 +42,7 @@ BUILD := build SOURCES := source DATA := data INCLUDES := include ../../libraries/libvapours/include -ROMFS := romfs - -# Output folders for autogenerated files in romfs -OUT_SHADERS := shaders +#ROMFS := romfs APP_TITLE := USB File Transfer APP_AUTHOR := Atmosphere-NX @@ -61,12 +58,12 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++23 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++20 ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -LIBS := -ldeko3d -lnx -lm +LIBS := -lnx #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -93,7 +90,6 @@ export DEPSDIR := $(CURDIR)/$(BUILD) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -GLSLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.glsl))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- @@ -159,61 +155,19 @@ ifneq ($(APP_TITLEID),) export NACPFLAGS += --titleid=$(APP_TITLEID) endif -ifneq ($(strip $(ROMFS)),) - ROMFS_TARGETS := - ROMFS_FOLDERS := - ifneq ($(strip $(OUT_SHADERS)),) - ROMFS_SHADERS := $(ROMFS)/$(OUT_SHADERS) - ROMFS_TARGETS += $(patsubst %.glsl, $(ROMFS_SHADERS)/%.dksh, $(GLSLFILES)) - ROMFS_FOLDERS += $(ROMFS_SHADERS) - endif - - export ROMFS_DEPS := $(foreach file,$(ROMFS_TARGETS),$(CURDIR)/$(file)) +ifneq ($(ROMFS),) export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) endif .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- -all: $(ROMFS_TARGETS) | $(BUILD) +all: $(BUILD) $(BUILD): @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile -ifneq ($(strip $(ROMFS_TARGETS)),) - -$(ROMFS_TARGETS): | $(ROMFS_FOLDERS) - -$(ROMFS_FOLDERS): - @mkdir -p $@ - -$(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl - @echo {vert} $(notdir $<) - @uam -s vert -o $@ $< - -$(ROMFS_SHADERS)/%_tcsh.dksh: %_tcsh.glsl - @echo {tess_ctrl} $(notdir $<) - @uam -s tess_ctrl -o $@ $< - -$(ROMFS_SHADERS)/%_tesh.dksh: %_tesh.glsl - @echo {tess_eval} $(notdir $<) - @uam -s tess_eval -o $@ $< - -$(ROMFS_SHADERS)/%_gsh.dksh: %_gsh.glsl - @echo {geom} $(notdir $<) - @uam -s geom -o $@ $< - -$(ROMFS_SHADERS)/%_fsh.dksh: %_fsh.glsl - @echo {frag} $(notdir $<) - @uam -s frag -o $@ $< - -$(ROMFS_SHADERS)/%.dksh: %.glsl - @echo {comp} $(notdir $<) - @uam -s comp -o $@ $< - -endif - #--------------------------------------------------------------------------------- clean: @echo clean ... @@ -238,9 +192,9 @@ ifeq ($(strip $(APP_JSON)),) all : $(OUTPUT).nro ifeq ($(strip $(NO_NACP)),) -$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp $(ROMFS_DEPS) +$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp else -$(OUTPUT).nro : $(OUTPUT).elf $(ROMFS_DEPS) +$(OUTPUT).nro : $(OUTPUT).elf endif else diff --git a/troposphere/haze/include/haze/common.hpp b/troposphere/haze/include/haze/common.hpp index 2859b0d50..5ebaf5861 100644 --- a/troposphere/haze/include/haze/common.hpp +++ b/troposphere/haze/include/haze/common.hpp @@ -42,4 +42,6 @@ namespace haze { using Result = ::ams::Result; + static constexpr u32 UsbBulkPacketBufferSize = 1_MB; + } diff --git a/troposphere/haze/include/haze/console_main_loop.hpp b/troposphere/haze/include/haze/console_main_loop.hpp index 184c36fc6..b91281615 100644 --- a/troposphere/haze/include/haze/console_main_loop.hpp +++ b/troposphere/haze/include/haze/console_main_loop.hpp @@ -143,7 +143,7 @@ namespace haze { if (m_is_applet_mode) { /* Print "Applet Mode" in red text. */ - printf("\n" CONSOLE_ESC(31;1m) "Applet Mode" CONSOLE_ESC(0m) "\n"); + printf("\n" CONSOLE_ESC(38;5;196m) "Applet Mode" CONSOLE_ESC(0m) "\n"); } consoleUpdate(nullptr); diff --git a/troposphere/haze/include/haze/ptp.hpp b/troposphere/haze/include/haze/ptp.hpp index beca16842..771b126ce 100644 --- a/troposphere/haze/include/haze/ptp.hpp +++ b/troposphere/haze/include/haze/ptp.hpp @@ -72,11 +72,6 @@ namespace haze { PtpOperationCode_GetFilesystemManifest = 0x1023, PtpOperationCode_GetStreamInfo = 0x1024, PtpOperationCode_GetStream = 0x1025, - PtpOperationCode_AndroidGetPartialObject64 = 0x95c1, - PtpOperationCode_AndroidSendPartialObject = 0x95c2, - PtpOperationCode_AndroidTruncateObject = 0x95c3, - PtpOperationCode_AndroidBeginEditObject = 0x95c4, - PtpOperationCode_AndroidEndEditObject = 0x95c5, PtpOperationCode_MtpGetObjectPropsSupported = 0x9801, PtpOperationCode_MtpGetObjectPropDesc = 0x9802, PtpOperationCode_MtpGetObjectPropValue = 0x9803, diff --git a/troposphere/haze/include/haze/ptp_object_heap.hpp b/troposphere/haze/include/haze/ptp_object_heap.hpp index ac3484e5d..fe1090a32 100644 --- a/troposphere/haze/include/haze/ptp_object_heap.hpp +++ b/troposphere/haze/include/haze/ptp_object_heap.hpp @@ -111,14 +111,6 @@ namespace haze { } constexpr void Deallocate(void *p, size_t n) { - /* Check for overflow in alignment. */ - if (!util::CanAddWithoutOverflow(n, alignof(u64) - 1)) { - return; - } - - /* Align the amount to satisfy allocation for u64. */ - n = util::AlignUp(n, alignof(u64)); - /* If the pointer was the last allocation, return the memory to the heap. */ if (static_cast(p) + n == this->GetNextAddress()) { m_next_address = this->GetNextAddress() - n; diff --git a/troposphere/haze/include/haze/ptp_responder.hpp b/troposphere/haze/include/haze/ptp_responder.hpp index 8dc996cdd..eac5aa330 100644 --- a/troposphere/haze/include/haze/ptp_responder.hpp +++ b/troposphere/haze/include/haze/ptp_responder.hpp @@ -19,7 +19,6 @@ #include #include #include -#include namespace haze { @@ -31,13 +30,12 @@ namespace haze { FileSystemProxy m_fs; PtpUsbBulkContainer m_request_header; PtpObjectHeap *m_object_heap; - PtpBuffers* m_buffers; u32 m_send_object_id; bool m_session_open; PtpObjectDatabase m_object_database; public: - constexpr explicit PtpResponder() : m_usb_server(), m_fs(), m_request_header(), m_object_heap(), m_buffers(), m_send_object_id(), m_session_open(), m_object_database() { /* ... */ } + constexpr explicit PtpResponder() : m_usb_server(), m_fs(), m_request_header(), m_object_heap(), m_send_object_id(), m_session_open(), m_object_database() { /* ... */ } Result Initialize(EventReactor *reactor, PtpObjectHeap *object_heap); void Finalize(); @@ -50,14 +48,10 @@ namespace haze { Result HandleCommandRequest(PtpDataParser &dp); void ForceCloseSession(); - Result WriteResponse(PtpResponseCode code, const void* data, size_t size); + template + Result WriteResponse(PtpResponseCode code, Data &&data); Result WriteResponse(PtpResponseCode code); - template requires (util::is_pod::value) - Result WriteResponse(PtpResponseCode code, const Data &data) { - R_RETURN(this->WriteResponse(code, std::addressof(data), sizeof(data))); - } - /* PTP operations. */ Result GetDeviceInfo(PtpDataParser &dp); Result OpenSession(PtpDataParser &dp); @@ -71,19 +65,11 @@ namespace haze { Result SendObject(PtpDataParser &dp); Result DeleteObject(PtpDataParser &dp); - /* Android operations. */ - Result GetPartialObject64(PtpDataParser &dp); - Result SendPartialObject(PtpDataParser &dp); - Result TruncateObject(PtpDataParser &dp); - Result BeginEditObject(PtpDataParser &dp); - Result EndEditObject(PtpDataParser &dp); - /* MTP operations. */ Result GetObjectPropsSupported(PtpDataParser &dp); Result GetObjectPropDesc(PtpDataParser &dp); Result GetObjectPropValue(PtpDataParser &dp); Result SetObjectPropValue(PtpDataParser &dp); - Result GetObjectPropList(PtpDataParser &dp); }; } diff --git a/troposphere/haze/include/haze/ptp_responder_types.hpp b/troposphere/haze/include/haze/ptp_responder_types.hpp deleted file mode 100644 index fd91e6d79..000000000 --- a/troposphere/haze/include/haze/ptp_responder_types.hpp +++ /dev/null @@ -1,183 +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 . - */ -#pragma once - -#include - -namespace haze { - - constexpr UsbCommsInterfaceInfo MtpInterfaceInfo = { - .bInterfaceClass = 0x06, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x01, - }; - - /* This is a VID:PID recognized by libmtp. */ - constexpr u16 SwitchMtpIdVendor = 0x057e; - constexpr u16 SwitchMtpIdProduct = 0x201d; - - /* Constants used for MTP GetDeviceInfo response. */ - constexpr u16 MtpStandardVersion = 100; - constexpr u32 MtpVendorExtensionId = 6; - constexpr auto MtpVendorExtensionDesc = "microsoft.com: 1.0;"; - constexpr u16 MtpFunctionalModeDefault = 0; - constexpr auto MtpDeviceManufacturer = "Nintendo"; - constexpr auto MtpDeviceModel = "Nintendo Switch"; - - enum StorageId : u32 { - StorageId_SdmcFs = 0xffffffffu - 1, - }; - - constexpr PtpOperationCode SupportedOperationCodes[] = { - PtpOperationCode_GetDeviceInfo, - PtpOperationCode_OpenSession, - PtpOperationCode_CloseSession, - PtpOperationCode_GetStorageIds, - PtpOperationCode_GetStorageInfo, - PtpOperationCode_GetObjectHandles, - PtpOperationCode_GetObjectInfo, - PtpOperationCode_GetObject, - PtpOperationCode_SendObjectInfo, - PtpOperationCode_SendObject, - PtpOperationCode_DeleteObject, - PtpOperationCode_MtpGetObjectPropsSupported, - PtpOperationCode_MtpGetObjectPropDesc, - PtpOperationCode_MtpGetObjectPropValue, - PtpOperationCode_MtpSetObjectPropValue, - PtpOperationCode_MtpGetObjPropList, - PtpOperationCode_AndroidGetPartialObject64, - PtpOperationCode_AndroidSendPartialObject, - PtpOperationCode_AndroidTruncateObject, - PtpOperationCode_AndroidBeginEditObject, - PtpOperationCode_AndroidEndEditObject, - }; - - constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ }; - constexpr const PtpDevicePropertyCode SupportedDeviceProperties[] = { /* ... */ }; - constexpr const PtpObjectFormatCode SupportedCaptureFormats[] = { /* ... */ }; - - constexpr const PtpObjectFormatCode SupportedPlaybackFormats[] = { - PtpObjectFormatCode_Undefined, - PtpObjectFormatCode_Association, - }; - - constexpr const PtpObjectPropertyCode SupportedObjectProperties[] = { - PtpObjectPropertyCode_StorageId, - PtpObjectPropertyCode_ObjectFormat, - PtpObjectPropertyCode_ObjectSize, - PtpObjectPropertyCode_ObjectFileName, - PtpObjectPropertyCode_ParentObject, - PtpObjectPropertyCode_PersistentUniqueObjectIdentifier, - }; - - constexpr bool IsSupportedObjectPropertyCode(PtpObjectPropertyCode c) { - for (size_t i = 0; i < util::size(SupportedObjectProperties); i++) { - if (SupportedObjectProperties[i] == c) { - return true; - } - } - - return false; - } - - constexpr const StorageId SupportedStorageIds[] = { - StorageId_SdmcFs, - }; - - struct PtpStorageInfo { - PtpStorageType storage_type; - PtpFilesystemType filesystem_type; - PtpAccessCapability access_capability; - u64 max_capacity; - u64 free_space_in_bytes; - u32 free_space_in_images; - const char *storage_description; - const char *volume_label; - }; - - constexpr PtpStorageInfo DefaultStorageInfo = { - .storage_type = PtpStorageType_FixedRam, - .filesystem_type = PtpFilesystemType_GenericHierarchical, - .access_capability = PtpAccessCapability_ReadWrite, - .max_capacity = 0, - .free_space_in_bytes = 0, - .free_space_in_images = 0, - .storage_description = "", - .volume_label = "", - }; - - struct PtpObjectInfo { - StorageId storage_id; - PtpObjectFormatCode object_format; - PtpProtectionStatus protection_status; - u32 object_compressed_size; - u16 thumb_format; - u32 thumb_compressed_size; - u32 thumb_width; - u32 thumb_height; - u32 image_width; - u32 image_height; - u32 image_depth; - u32 parent_object; - PtpAssociationType association_type; - u32 association_desc; - u32 sequence_number; - const char *filename; - const char *capture_date; - const char *modification_date; - const char *keywords; - }; - - constexpr PtpObjectInfo DefaultObjectInfo = { - .storage_id = StorageId_SdmcFs, - .object_format = {}, - .protection_status = PtpProtectionStatus_NoProtection, - .object_compressed_size = 0, - .thumb_format = 0, - .thumb_compressed_size = 0, - .thumb_width = 0, - .thumb_height = 0, - .image_width = 0, - .image_height = 0, - .image_depth = 0, - .parent_object = PtpGetObjectHandles_RootParent, - .association_type = PtpAssociationType_Undefined, - .association_desc = 0, - .sequence_number = 0, - .filename = nullptr, - .capture_date = "", - .modification_date = "", - .keywords = "", - }; - - constexpr u32 UsbBulkPacketBufferSize = 1_MB; - constexpr u64 FsBufferSize = UsbBulkPacketBufferSize; - constexpr s64 DirectoryReadSize = 32; - - struct PtpBuffers { - char filename_string_buffer[PtpStringMaxLength + 1]; - char capture_date_string_buffer[PtpStringMaxLength + 1]; - char modification_date_string_buffer[PtpStringMaxLength + 1]; - char keywords_string_buffer[PtpStringMaxLength + 1]; - - FsDirectoryEntry file_system_entry_buffer[DirectoryReadSize]; - u8 file_system_data_buffer[FsBufferSize]; - - alignas(4_KB) u8 usb_bulk_write_buffer[UsbBulkPacketBufferSize]; - alignas(4_KB) u8 usb_bulk_read_buffer[UsbBulkPacketBufferSize]; - }; - -} diff --git a/troposphere/haze/include/haze/results.hpp b/troposphere/haze/include/haze/results.hpp index ea3933ddf..fec0e84de 100644 --- a/troposphere/haze/include/haze/results.hpp +++ b/troposphere/haze/include/haze/results.hpp @@ -37,8 +37,5 @@ namespace haze { R_DEFINE_ERROR_RESULT(UnknownRequestType, 13); R_DEFINE_ERROR_RESULT(UnknownPropertyCode, 14); R_DEFINE_ERROR_RESULT(InvalidPropertyValue, 15); - R_DEFINE_ERROR_RESULT(InvalidArgument, 16); - R_DEFINE_ERROR_RESULT(GroupSpecified, 17); - R_DEFINE_ERROR_RESULT(DepthSpecified, 18); } diff --git a/troposphere/haze/source/console_fsh.glsl b/troposphere/haze/source/console_fsh.glsl deleted file mode 100644 index 2875883ed..000000000 --- a/troposphere/haze/source/console_fsh.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version 460 - -layout (location = 0) noperspective in vec3 inTexCoord; -layout (location = 1) flat in vec4 inFrontPal; -layout (location = 2) flat in vec4 inBackPal; - -layout (location = 0) out vec4 outColor; - -layout (binding = 0) uniform sampler2DArray tileset; - -void main() -{ - float value = texture(tileset, inTexCoord).r; - outColor = mix(inBackPal, inFrontPal, value); -} diff --git a/troposphere/haze/source/console_vsh.glsl b/troposphere/haze/source/console_vsh.glsl deleted file mode 100644 index 59a5b79a2..000000000 --- a/troposphere/haze/source/console_vsh.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#version 460 - -layout (location = 0) in float inTileId; -layout (location = 1) in uvec2 inColorId; - -layout (location = 0) out vec3 outTexCoord; -layout (location = 1) out vec4 outFrontPal; -layout (location = 2) out vec4 outBackPal; - -layout (std140, binding = 0) uniform Config -{ - vec4 dimensions; - vec4 vertices[3]; - vec4 palettes[24]; -} u; - -void main() -{ - float id = float(gl_InstanceID); - float tileRow = floor(id / u.dimensions.z); - float tileCol = id - tileRow * u.dimensions.z; - - vec2 basePos; - basePos.x = 2.0 * (tileCol + 0.5) / u.dimensions.z - 1.0; - basePos.y = 2.0 * (1.0 - (tileRow + 0.5) / u.dimensions.w) - 1.0; - - vec2 vtxData = u.vertices[gl_VertexID].xy; - vec2 scale = vec2(1.0) / u.dimensions.zw; - gl_Position.xy = vtxData * scale + basePos; - gl_Position.zw = vec2(0.5, 1.0); - - outTexCoord = vec3(u.vertices[gl_VertexID].zw, inTileId); - outFrontPal = u.palettes[inColorId.x]; - outBackPal = u.palettes[inColorId.y]; -} diff --git a/troposphere/haze/source/gpu_console.c b/troposphere/haze/source/gpu_console.c deleted file mode 100644 index cbfe62872..000000000 --- a/troposphere/haze/source/gpu_console.c +++ /dev/null @@ -1,487 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -// Define the desired number of framebuffers -#define FB_NUM 2 - -// Define the size of the memory block that will hold code -#define CODEMEMSIZE (64*1024) - -// Define the size of the memory block that will hold command lists -#define CMDMEMSIZE (64*1024) - -#define NUM_IMAGE_SLOTS 1 -#define NUM_SAMPLER_SLOTS 1 - -typedef struct { - float pos[2]; - float tex[2]; -} VertexDef; - -typedef struct { - float red; - float green; - float blue; - float alpha; -} PaletteColor; - -typedef struct { - float dimensions[4]; - VertexDef vertices[3]; - PaletteColor palettes[24]; -} ConsoleConfig; - -static const VertexDef g_vertexData[3] = { - { { 0.0f, +1.0f }, { 0.5f, 0.0f, } }, - { { -1.0f, -1.0f }, { 0.0f, 1.0f, } }, - { { +1.0f, -1.0f }, { 1.0f, 1.0f, } }, -}; - -static const PaletteColor g_paletteData[24] = { - { 0.0f, 0.0f, 0.0f, 0.0f }, // black - { 0.5f, 0.0f, 0.0f, 1.0f }, // red - { 0.0f, 0.5f, 0.0f, 1.0f }, // green - { 0.5f, 0.5f, 0.0f, 1.0f }, // yellow - { 0.0f, 0.0f, 0.5f, 1.0f }, // blue - { 0.5f, 0.0f, 0.5f, 1.0f }, // magenta - { 0.0f, 0.5f, 0.5f, 1.0f }, // cyan - { 0.75f, 0.75f, 0.75f, 1.0f }, // white - - { 0.5f, 0.5f, 0.5f, 1.0f }, // bright black - { 1.0f, 0.0f, 0.0f, 1.0f }, // bright red - { 0.0f, 1.0f, 0.0f, 1.0f }, // bright green - { 1.0f, 1.0f, 0.0f, 1.0f }, // bright yellow - { 0.0f, 0.0f, 1.0f, 1.0f }, // bright blue - { 1.0f, 0.0f, 1.0f, 1.0f }, // bright magenta - { 0.0f, 1.0f, 1.0f, 1.0f }, // bright cyan - { 1.0f, 1.0f, 1.0f, 1.0f }, // bright white - - { 0.0f, 0.0f, 0.0f, 0.0f }, // faint black - { 0.25f, 0.0f, 0.0f, 1.0f }, // faint red - { 0.0f, 0.25f, 0.0f, 1.0f }, // faint green - { 0.25f, 0.25f, 0.0f, 1.0f }, // faint yellow - { 0.0f, 0.0f, 0.25f, 1.0f }, // faint blue - { 0.25f, 0.0f, 0.25f, 1.0f }, // faint magenta - { 0.0f, 0.25f, 0.25f, 1.0f }, // faint cyan - { 0.375f, 0.375f, 0.375f, 1.0f }, // faint white -}; - -typedef struct { - uint16_t tileId; - uint8_t frontPal; - uint8_t backPal; -} ConsoleChar; - -static const DkVtxAttribState g_attribState[] = { - { .bufferId=0, .isFixed=0, .offset=offsetof(ConsoleChar,tileId), .size=DkVtxAttribSize_1x16, .type=DkVtxAttribType_Uscaled, .isBgra=0 }, - { .bufferId=0, .isFixed=0, .offset=offsetof(ConsoleChar,frontPal), .size=DkVtxAttribSize_2x8, .type=DkVtxAttribType_Uint, .isBgra=0 }, -}; - -static const DkVtxBufferState g_vtxbufState[] = { - { .stride=sizeof(ConsoleChar), .divisor=1 }, -}; - -struct GpuRenderer { - ConsoleRenderer base; - - bool initialized; - - DkDevice device; - DkQueue queue; - - DkMemBlock imageMemBlock; - DkMemBlock codeMemBlock; - DkMemBlock dataMemBlock; - - DkSwapchain swapchain; - DkImage framebuffers[FB_NUM]; - DkImage tileset; - ConsoleChar* charBuf; - - uint32_t codeMemOffset; - DkShader vertexShader; - DkShader fragmentShader; - - DkCmdBuf cmdbuf; - DkCmdList cmdsBindFramebuffer[FB_NUM]; - DkCmdList cmdsRender; - - DkFence lastRenderFence; -}; - -static struct GpuRenderer* GpuRenderer(PrintConsole* con) -{ - return (struct GpuRenderer*)con->renderer; -} - -static void GpuRenderer_destroy(struct GpuRenderer* r) -{ - // Make sure the queue is idle before destroying anything - dkQueueWaitIdle(r->queue); - - // Destroy all the resources we've created - dkQueueDestroy(r->queue); - dkCmdBufDestroy(r->cmdbuf); - dkSwapchainDestroy(r->swapchain); - dkMemBlockDestroy(r->dataMemBlock); - dkMemBlockDestroy(r->codeMemBlock); - dkMemBlockDestroy(r->imageMemBlock); - dkDeviceDestroy(r->device); - - // Clear out all state - memset(&r->initialized, 0, sizeof(*r) - offsetof(struct GpuRenderer, initialized)); -} - -// Simple function for loading a shader from the filesystem -static void GpuRenderer_loadShader(struct GpuRenderer* r, DkShader* pShader, const char* path) -{ - // Open the file, and retrieve its size - FILE* f = fopen(path, "rb"); - fseek(f, 0, SEEK_END); - uint32_t size = ftell(f); - rewind(f); - - // Look for a spot in the code memory block for loading this shader. Note that - // we are just using a simple incremental offset; this isn't a general purpose - // allocation algorithm. - uint32_t codeOffset = r->codeMemOffset; - r->codeMemOffset += (size + DK_SHADER_CODE_ALIGNMENT - 1) &~ (DK_SHADER_CODE_ALIGNMENT - 1); - - // Read the file into memory, and close the file - fread((uint8_t*)dkMemBlockGetCpuAddr(r->codeMemBlock) + codeOffset, size, 1, f); - fclose(f); - - // Initialize the user provided shader object with the code we've just loaded - DkShaderMaker shaderMaker; - dkShaderMakerDefaults(&shaderMaker, r->codeMemBlock, codeOffset); - dkShaderInitialize(pShader, &shaderMaker); -} - -static bool GpuRenderer_init(PrintConsole* con) -{ - struct GpuRenderer* r = GpuRenderer(con); - - if (r->initialized) { - // We're already initialized - return true; - } - - // Create the deko3d device, which is the root object - DkDeviceMaker deviceMaker; - dkDeviceMakerDefaults(&deviceMaker); - r->device = dkDeviceCreate(&deviceMaker); - - // Create the queue - DkQueueMaker queueMaker; - dkQueueMakerDefaults(&queueMaker, r->device); - queueMaker.flags = DkQueueFlags_Graphics; - r->queue = dkQueueCreate(&queueMaker); - - // Calculate required width/height for the framebuffers - u32 width = con->font.tileWidth * con->consoleWidth; - u32 height = con->font.tileHeight * con->consoleHeight; - u32 totalConSize = con->consoleWidth * con->consoleHeight; - - // Calculate layout for the framebuffers - DkImageLayoutMaker imageLayoutMaker; - dkImageLayoutMakerDefaults(&imageLayoutMaker, r->device); - imageLayoutMaker.flags = DkImageFlags_UsageRender | DkImageFlags_UsagePresent | DkImageFlags_HwCompression; - imageLayoutMaker.format = DkImageFormat_RGBA8_Unorm; - imageLayoutMaker.dimensions[0] = width; - imageLayoutMaker.dimensions[1] = height; - - // Calculate layout for the framebuffers - DkImageLayout framebufferLayout; - dkImageLayoutInitialize(&framebufferLayout, &imageLayoutMaker); - - // Calculate layout for the tileset - dkImageLayoutMakerDefaults(&imageLayoutMaker, r->device); - imageLayoutMaker.type = DkImageType_2DArray; - imageLayoutMaker.format = DkImageFormat_R32_Float; - imageLayoutMaker.dimensions[0] = con->font.tileWidth; - imageLayoutMaker.dimensions[1] = con->font.tileHeight; - imageLayoutMaker.dimensions[2] = con->font.numChars; - - // Calculate layout for the tileset - DkImageLayout tilesetLayout; - dkImageLayoutInitialize(&tilesetLayout, &imageLayoutMaker); - - // Retrieve necessary size and alignment for the framebuffers - uint32_t framebufferSize = dkImageLayoutGetSize(&framebufferLayout); - uint32_t framebufferAlign = dkImageLayoutGetAlignment(&framebufferLayout); - framebufferSize = (framebufferSize + framebufferAlign - 1) &~ (framebufferAlign - 1); - - // Retrieve necessary size and alignment for the tileset - uint32_t tilesetSize = dkImageLayoutGetSize(&tilesetLayout); - uint32_t tilesetAlign = dkImageLayoutGetAlignment(&tilesetLayout); - tilesetSize = (tilesetSize + tilesetAlign - 1) &~ (tilesetAlign - 1); - - // Create a memory block that will host the framebuffers and the tileset - DkMemBlockMaker memBlockMaker; - dkMemBlockMakerDefaults(&memBlockMaker, r->device, FB_NUM*framebufferSize + tilesetSize); - memBlockMaker.flags = DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image; - r->imageMemBlock = dkMemBlockCreate(&memBlockMaker); - - // Initialize the framebuffers with the layout and backing memory we've just created - DkImage const* swapchainImages[FB_NUM]; - for (unsigned i = 0; i < FB_NUM; i ++) { - swapchainImages[i] = &r->framebuffers[i]; - dkImageInitialize(&r->framebuffers[i], &framebufferLayout, r->imageMemBlock, i*framebufferSize); - } - - // Create a swapchain out of the framebuffers we've just initialized - DkSwapchainMaker swapchainMaker; - dkSwapchainMakerDefaults(&swapchainMaker, r->device, nwindowGetDefault(), swapchainImages, FB_NUM); - r->swapchain = dkSwapchainCreate(&swapchainMaker); - - // Initialize the tileset - dkImageInitialize(&r->tileset, &tilesetLayout, r->imageMemBlock, FB_NUM*framebufferSize); - - // Create a memory block onto which we will load shader code - dkMemBlockMakerDefaults(&memBlockMaker, r->device, CODEMEMSIZE); - memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached | DkMemBlockFlags_Code; - r->codeMemBlock = dkMemBlockCreate(&memBlockMaker); - r->codeMemOffset = 0; - - // Load our shaders (both vertex and fragment) - romfsInit(); - GpuRenderer_loadShader(r, &r->vertexShader, "romfs:/shaders/console_vsh.dksh"); - GpuRenderer_loadShader(r, &r->fragmentShader, "romfs:/shaders/console_fsh.dksh"); - - // Generate the descriptors - struct { - DkImageDescriptor images[NUM_IMAGE_SLOTS]; - DkSamplerDescriptor samplers[NUM_SAMPLER_SLOTS]; - } descriptors; - - // Generate a image descriptor for the tileset - DkImageView tilesetView; - dkImageViewDefaults(&tilesetView, &r->tileset); - dkImageDescriptorInitialize(&descriptors.images[0], &tilesetView, false, false); - - // Generate a sampler descriptor for the tileset - DkSampler sampler; - dkSamplerDefaults(&sampler); - sampler.wrapMode[0] = DkWrapMode_ClampToEdge; - sampler.wrapMode[1] = DkWrapMode_ClampToEdge; - sampler.minFilter = DkFilter_Nearest; - sampler.magFilter = DkFilter_Nearest; - dkSamplerDescriptorInitialize(&descriptors.samplers[0], &sampler); - - uint32_t descriptorsOffset = CMDMEMSIZE; - uint32_t configOffset = (descriptorsOffset + sizeof(descriptors) + DK_UNIFORM_BUF_ALIGNMENT - 1) &~ (DK_UNIFORM_BUF_ALIGNMENT - 1); - uint32_t configSize = (sizeof(ConsoleConfig) + DK_UNIFORM_BUF_ALIGNMENT - 1) &~ (DK_UNIFORM_BUF_ALIGNMENT - 1); - - uint32_t charBufOffset = configOffset + configSize; - uint32_t charBufSize = totalConSize * sizeof(ConsoleChar); - - // Create a memory block which will be used for recording command lists using a command buffer - dkMemBlockMakerDefaults(&memBlockMaker, r->device, - (charBufOffset + charBufSize + DK_MEMBLOCK_ALIGNMENT - 1) &~ (DK_MEMBLOCK_ALIGNMENT - 1) - ); - memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached; - r->dataMemBlock = dkMemBlockCreate(&memBlockMaker); - - // Create a command buffer object - DkCmdBufMaker cmdbufMaker; - dkCmdBufMakerDefaults(&cmdbufMaker, r->device); - r->cmdbuf = dkCmdBufCreate(&cmdbufMaker); - - // Feed our memory to the command buffer so that we can start recording commands - dkCmdBufAddMemory(r->cmdbuf, r->dataMemBlock, 0, CMDMEMSIZE); - - // Create a temporary buffer that will hold the tileset - dkMemBlockMakerDefaults(&memBlockMaker, r->device, - (sizeof(float)*con->font.tileWidth*con->font.tileHeight*con->font.numChars + DK_MEMBLOCK_ALIGNMENT - 1) &~ (DK_MEMBLOCK_ALIGNMENT - 1) - ); - memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached; - DkMemBlock scratchMemBlock = dkMemBlockCreate(&memBlockMaker); - float* scratchMem = (float*)dkMemBlockGetCpuAddr(scratchMemBlock); - - // Unpack 1bpp tileset into a texture image the GPU can read - unsigned packedTileWidth = (con->font.tileWidth+7)/8; - for (unsigned tile = 0; tile < con->font.numChars; tile ++) { - const uint8_t* data = (const uint8_t*)con->font.gfx + con->font.tileHeight*packedTileWidth*tile; - for (unsigned y = 0; y < con->font.tileHeight; y ++) { - const uint8_t* row = &data[packedTileWidth*(y+1)]; - uint8_t c = 0; - for (unsigned x = 0; x < con->font.tileWidth; x ++) { - if (!(x & 7)) - c = *--row; - *scratchMem++ = (c & 0x80) ? 1.0f : 0.0f; - c <<= 1; - } - } - } - - // Set up configuration - DkGpuAddr configAddr = dkMemBlockGetGpuAddr(r->dataMemBlock) + configOffset; - ConsoleConfig consoleConfig = {}; - consoleConfig.dimensions[0] = width; - consoleConfig.dimensions[1] = height; - consoleConfig.dimensions[2] = con->consoleWidth; - consoleConfig.dimensions[3] = con->consoleHeight; - memcpy(consoleConfig.vertices, g_vertexData, sizeof(g_vertexData)); - memcpy(consoleConfig.palettes, g_paletteData, sizeof(g_paletteData)); - - // Generate a temporary command list for uploading stuff and run it - DkGpuAddr descriptorSet = dkMemBlockGetGpuAddr(r->dataMemBlock) + descriptorsOffset; - DkCopyBuf copySrc = { dkMemBlockGetGpuAddr(scratchMemBlock), 0, 0 }; - DkImageRect copyDst = { 0, 0, 0, con->font.tileWidth, con->font.tileHeight, con->font.numChars }; - dkCmdBufPushData(r->cmdbuf, descriptorSet, &descriptors, sizeof(descriptors)); - dkCmdBufPushConstants(r->cmdbuf, configAddr, configSize, 0, sizeof(consoleConfig), &consoleConfig); - dkCmdBufBindImageDescriptorSet(r->cmdbuf, descriptorSet, NUM_IMAGE_SLOTS); - dkCmdBufBindSamplerDescriptorSet(r->cmdbuf, descriptorSet + NUM_IMAGE_SLOTS*sizeof(DkImageDescriptor), NUM_SAMPLER_SLOTS); - dkCmdBufCopyBufferToImage(r->cmdbuf, ©Src, &tilesetView, ©Dst, 0); - dkQueueSubmitCommands(r->queue, dkCmdBufFinishList(r->cmdbuf)); - dkQueueFlush(r->queue); - dkQueueWaitIdle(r->queue); - dkCmdBufClear(r->cmdbuf); - - // Destroy the scratch memory block since we don't need it anymore - dkMemBlockDestroy(scratchMemBlock); - - // Retrieve the address of the character buffer - DkGpuAddr charBufAddr = dkMemBlockGetGpuAddr(r->dataMemBlock) + charBufOffset; - r->charBuf = (ConsoleChar*)((uint8_t*)dkMemBlockGetCpuAddr(r->dataMemBlock) + charBufOffset); - memset(r->charBuf, 0, charBufSize); - - // Generate a command list for each framebuffer, which will bind each of them as a render target - for (unsigned i = 0; i < FB_NUM; i ++) { - DkImageView imageView; - dkImageViewDefaults(&imageView, &r->framebuffers[i]); - dkCmdBufBindRenderTarget(r->cmdbuf, &imageView, NULL); - r->cmdsBindFramebuffer[i] = dkCmdBufFinishList(r->cmdbuf); - } - - // Declare structs that will be used for binding state - DkViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f }; - DkScissor scissor = { 0, 0, width, height }; - DkShader const* shaders[] = { &r->vertexShader, &r->fragmentShader }; - DkRasterizerState rasterizerState; - DkColorState colorState; - DkColorWriteState colorWriteState; - - // Initialize state structs with the deko3d defaults - dkRasterizerStateDefaults(&rasterizerState); - dkColorStateDefaults(&colorState); - dkColorWriteStateDefaults(&colorWriteState); - - rasterizerState.fillRectangleEnable = true; - colorState.alphaCompareOp = DkCompareOp_Greater; - - // Generate the main rendering command list - dkCmdBufSetViewports(r->cmdbuf, 0, &viewport, 1); - dkCmdBufSetScissors(r->cmdbuf, 0, &scissor, 1); - //dkCmdBufClearColorFloat(r->cmdbuf, 0, DkColorMask_RGBA, 0.125f, 0.294f, 0.478f, 0.0f); - dkCmdBufClearColorFloat(r->cmdbuf, 0, DkColorMask_RGBA, 0.0f, 0.0f, 0.0f, 0.0f); - dkCmdBufBindShaders(r->cmdbuf, DkStageFlag_GraphicsMask, shaders, sizeof(shaders)/sizeof(shaders[0])); - dkCmdBufBindRasterizerState(r->cmdbuf, &rasterizerState); - dkCmdBufBindColorState(r->cmdbuf, &colorState); - dkCmdBufBindColorWriteState(r->cmdbuf, &colorWriteState); - dkCmdBufBindUniformBuffer(r->cmdbuf, DkStage_Vertex, 0, configAddr, configSize); - dkCmdBufBindTexture(r->cmdbuf, DkStage_Fragment, 0, dkMakeTextureHandle(0, 0)); - dkCmdBufBindVtxAttribState(r->cmdbuf, g_attribState, sizeof(g_attribState)/sizeof(g_attribState[0])); - dkCmdBufBindVtxBufferState(r->cmdbuf, g_vtxbufState, sizeof(g_vtxbufState)/sizeof(g_vtxbufState[0])); - dkCmdBufBindVtxBuffer(r->cmdbuf, 0, charBufAddr, charBufSize); - dkCmdBufSetAlphaRef(r->cmdbuf, 0.0f); - dkCmdBufDraw(r->cmdbuf, DkPrimitive_Triangles, 3, totalConSize, 0, 0); - r->cmdsRender = dkCmdBufFinishList(r->cmdbuf); - - r->initialized = true; - return true; -} - -static void GpuRenderer_deinit(PrintConsole* con) -{ - struct GpuRenderer* r = GpuRenderer(con); - - if (r->initialized) { - GpuRenderer_destroy(r); - } -} - -static void GpuRenderer_drawChar(PrintConsole* con, int x, int y, int c) -{ - struct GpuRenderer* r = GpuRenderer(con); - - int writingColor = con->fg; - int screenColor = con->bg; - - if (con->flags & CONSOLE_COLOR_BOLD) { - writingColor += 8; - } else if (con->flags & CONSOLE_COLOR_FAINT) { - writingColor += 16; - } - - if (con->flags & CONSOLE_COLOR_REVERSE) { - int tmp = writingColor; - writingColor = screenColor; - screenColor = tmp; - } - - // Wait for the fence - dkFenceWait(&r->lastRenderFence, UINT64_MAX); - - ConsoleChar* pos = &r->charBuf[y*con->consoleWidth+x]; - pos->tileId = c; - pos->frontPal = writingColor; - pos->backPal = screenColor; -} - -static void GpuRenderer_scrollWindow(PrintConsole* con) -{ - struct GpuRenderer* r = GpuRenderer(con); - - // Wait for the fence - dkFenceWait(&r->lastRenderFence, UINT64_MAX); - - // Perform the scrolling - for (int y = 0; y < con->windowHeight-1; y ++) { - memcpy( - &r->charBuf[(con->windowY+y+0)*con->consoleWidth + con->windowX], - &r->charBuf[(con->windowY+y+1)*con->consoleWidth + con->windowX], - sizeof(ConsoleChar)*con->windowWidth); - } -} - -static void GpuRenderer_flushAndSwap(PrintConsole* con) -{ - struct GpuRenderer* r = GpuRenderer(con); - - // Acquire a framebuffer from the swapchain (and wait for it to be available) - int slot = dkQueueAcquireImage(r->queue, r->swapchain); - - // Run the command list that binds said framebuffer as a render target - dkQueueSubmitCommands(r->queue, r->cmdsBindFramebuffer[slot]); - - // Run the main rendering command list - dkQueueSubmitCommands(r->queue, r->cmdsRender); - - // Signal the fence - dkQueueSignalFence(r->queue, &r->lastRenderFence, false); - - // Now that we are done rendering, present it to the screen - dkQueuePresentImage(r->queue, r->swapchain, slot); -} - -static struct GpuRenderer s_gpuRenderer = -{ - { - GpuRenderer_init, - GpuRenderer_deinit, - GpuRenderer_drawChar, - GpuRenderer_scrollWindow, - GpuRenderer_flushAndSwap, - } -}; - -ConsoleRenderer* getDefaultConsoleRenderer(void) -{ - return &s_gpuRenderer.base; -} diff --git a/troposphere/haze/source/ptp_object_heap.cpp b/troposphere/haze/source/ptp_object_heap.cpp index c3d947342..2157b59c5 100644 --- a/troposphere/haze/source/ptp_object_heap.cpp +++ b/troposphere/haze/source/ptp_object_heap.cpp @@ -19,8 +19,8 @@ namespace haze { namespace { - /* Allow 30MiB for use by libnx. */ - static constexpr size_t LibnxReservedMemorySize = 30_MB; + /* Allow 20MiB for use by libnx. */ + static constexpr size_t LibnxReservedMemorySize = 20_MB; } diff --git a/troposphere/haze/source/ptp_responder.cpp b/troposphere/haze/source/ptp_responder.cpp index 8194aaf7b..6086c2cce 100644 --- a/troposphere/haze/source/ptp_responder.cpp +++ b/troposphere/haze/source/ptp_responder.cpp @@ -16,22 +16,167 @@ #include #include #include -#include namespace haze { namespace { - PtpBuffers *GetBuffers() { - static constinit PtpBuffers buffers = {}; - return std::addressof(buffers); + constexpr UsbCommsInterfaceInfo MtpInterfaceInfo = { + .bInterfaceClass = 0x06, + .bInterfaceSubClass = 0x01, + .bInterfaceProtocol = 0x01, + }; + + /* This is a VID:PID recognized by libmtp. */ + constexpr u16 SwitchMtpIdVendor = 0x057e; + constexpr u16 SwitchMtpIdProduct = 0x201d; + + /* Constants used for MTP GetDeviceInfo response. */ + constexpr u16 MtpStandardVersion = 100; + constexpr u32 MtpVendorExtensionId = 6; + constexpr auto MtpVendorExtensionDesc = "microsoft.com: 1.0;"; + constexpr u16 MtpFunctionalModeDefault = 0; + constexpr auto MtpDeviceManufacturer = "Nintendo"; + constexpr auto MtpDeviceModel = "Nintendo Switch"; + + enum StorageId : u32 { + StorageId_SdmcFs = 0xffffffffu - 1, + }; + + constexpr PtpOperationCode SupportedOperationCodes[] = { + PtpOperationCode_GetDeviceInfo, + PtpOperationCode_OpenSession, + PtpOperationCode_CloseSession, + PtpOperationCode_GetStorageIds, + PtpOperationCode_GetStorageInfo, + PtpOperationCode_GetObjectHandles, + PtpOperationCode_GetObjectInfo, + PtpOperationCode_GetObject, + PtpOperationCode_SendObjectInfo, + PtpOperationCode_SendObject, + PtpOperationCode_DeleteObject, + PtpOperationCode_MtpGetObjectPropsSupported, + PtpOperationCode_MtpGetObjectPropDesc, + PtpOperationCode_MtpGetObjectPropValue, + PtpOperationCode_MtpSetObjectPropValue, + }; + + constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ }; + constexpr const PtpDevicePropertyCode SupportedDeviceProperties[] = { /* ... */ }; + constexpr const PtpObjectFormatCode SupportedCaptureFormats[] = { /* ... */ }; + + constexpr const PtpObjectFormatCode SupportedPlaybackFormats[] = { + PtpObjectFormatCode_Undefined, + PtpObjectFormatCode_Association, + }; + + constexpr const PtpObjectPropertyCode SupportedObjectProperties[] = { + PtpObjectPropertyCode_StorageId, + PtpObjectPropertyCode_ObjectFormat, + PtpObjectPropertyCode_ObjectSize, + PtpObjectPropertyCode_ObjectFileName, + PtpObjectPropertyCode_ParentObject, + PtpObjectPropertyCode_PersistentUniqueObjectIdentifier, + }; + + constexpr bool IsSupportedObjectPropertyCode(PtpObjectPropertyCode c) { + for (size_t i = 0; i < util::size(SupportedObjectProperties); i++) { + if (SupportedObjectProperties[i] == c) { + return true; + } + } + + return false; } + constexpr const StorageId SupportedStorageIds[] = { + StorageId_SdmcFs, + }; + + struct PtpStorageInfo { + PtpStorageType storage_type; + PtpFilesystemType filesystem_type; + PtpAccessCapability access_capability; + u64 max_capacity; + u64 free_space_in_bytes; + u32 free_space_in_images; + const char *storage_description; + const char *volume_label; + }; + + constexpr PtpStorageInfo DefaultStorageInfo = { + .storage_type = PtpStorageType_FixedRam, + .filesystem_type = PtpFilesystemType_GenericHierarchical, + .access_capability = PtpAccessCapability_ReadWrite, + .max_capacity = 0, + .free_space_in_bytes = 0, + .free_space_in_images = 0, + .storage_description = "", + .volume_label = "", + }; + + struct PtpObjectInfo { + StorageId storage_id; + PtpObjectFormatCode object_format; + PtpProtectionStatus protection_status; + u32 object_compressed_size; + u16 thumb_format; + u32 thumb_compressed_size; + u32 thumb_width; + u32 thumb_height; + u32 image_width; + u32 image_height; + u32 image_depth; + u32 parent_object; + PtpAssociationType association_type; + u32 association_desc; + u32 sequence_number; + const char *filename; + const char *capture_date; + const char *modification_date; + const char *keywords; + }; + + constexpr PtpObjectInfo DefaultObjectInfo = { + .storage_id = StorageId_SdmcFs, + .object_format = {}, + .protection_status = PtpProtectionStatus_NoProtection, + .object_compressed_size = 0, + .thumb_format = 0, + .thumb_compressed_size = 0, + .thumb_width = 0, + .thumb_height = 0, + .image_width = 0, + .image_height = 0, + .image_depth = 0, + .parent_object = PtpGetObjectHandles_RootParent, + .association_type = PtpAssociationType_Undefined, + .association_desc = 0, + .sequence_number = 0, + .filename = nullptr, + .capture_date = "", + .modification_date = "", + .keywords = "", + }; + + constexpr s64 DirectoryReadSize = 32; + constexpr u64 FsBufferSize = haze::UsbBulkPacketBufferSize; + + constinit char g_filename_str[PtpStringMaxLength + 1] = {}; + constinit char g_capture_date_str[PtpStringMaxLength + 1] = {}; + constinit char g_modification_date_str[PtpStringMaxLength + 1] = {}; + constinit char g_keywords_str[PtpStringMaxLength + 1] = {}; + + constinit FsDirectoryEntry g_dir_entries[DirectoryReadSize] = {}; + constinit u8 g_fs_buffer[FsBufferSize] = {}; + + alignas(4_KB) constinit u8 g_bulk_write_buffer[haze::UsbBulkPacketBufferSize] = {}; + alignas(4_KB) constinit u8 g_bulk_read_buffer[haze::UsbBulkPacketBufferSize] = {}; + } Result PtpResponder::Initialize(EventReactor *reactor, PtpObjectHeap *object_heap) { m_object_heap = object_heap; - m_buffers = GetBuffers(); /* Configure fs proxy. */ m_fs.Initialize(reactor, fsdevGetDeviceFileSystem("sdmc")); @@ -91,15 +236,6 @@ namespace haze { R_CATCH(haze::ResultInvalidPropertyValue) { R_TRY(this->WriteResponse(PtpResponseCode_MtpInvalidObjectPropValue)); } - R_CATCH(haze::ResultGroupSpecified) { - R_TRY(this->WriteResponse(PtpResponseCode_MtpSpecificationByGroupUnsupported)); - } - R_CATCH(haze::ResultDepthSpecified) { - R_TRY(this->WriteResponse(PtpResponseCode_MtpSpecificationByDepthUnsupported)); - } - R_CATCH(haze::ResultInvalidArgument) { - R_TRY(this->WriteResponse(PtpResponseCode_GeneralError)); - } R_CATCH_MODULE(fs) { /* Errors from fs are typically recoverable. */ R_TRY(this->WriteResponse(PtpResponseCode_GeneralError)); @@ -110,7 +246,7 @@ namespace haze { } Result PtpResponder::HandleRequestImpl() { - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); + PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); R_TRY(dp.Read(std::addressof(m_request_header))); switch (m_request_header.type) { @@ -140,12 +276,6 @@ namespace haze { case PtpOperationCode_MtpGetObjectPropDesc: R_RETURN(this->GetObjectPropDesc(dp)); break; case PtpOperationCode_MtpGetObjectPropValue: R_RETURN(this->GetObjectPropValue(dp)); break; case PtpOperationCode_MtpSetObjectPropValue: R_RETURN(this->SetObjectPropValue(dp)); break; - case PtpOperationCode_MtpGetObjPropList: R_RETURN(this->GetObjectPropList(dp)); break; - case PtpOperationCode_AndroidGetPartialObject64: R_RETURN(this->GetPartialObject64(dp)); break; - case PtpOperationCode_AndroidSendPartialObject: R_RETURN(this->SendPartialObject(dp)); break; - case PtpOperationCode_AndroidTruncateObject: R_RETURN(this->TruncateObject(dp)); break; - case PtpOperationCode_AndroidBeginEditObject: R_RETURN(this->BeginEditObject(dp)); break; - case PtpOperationCode_AndroidEndEditObject: R_RETURN(this->EndEditObject(dp)); break; default: R_THROW(haze::ResultOperationNotSupported()); } } @@ -157,17 +287,756 @@ namespace haze { } } - Result PtpResponder::WriteResponse(PtpResponseCode code, const void* data, size_t size) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - R_TRY(db.AddResponseHeader(m_request_header, code, size)); - R_TRY(db.AddBuffer(reinterpret_cast(data), size)); + template + Result PtpResponder::WriteResponse(PtpResponseCode code, Data &&data) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + R_TRY(db.AddResponseHeader(m_request_header, code, sizeof(Data))); + R_TRY(db.Add(data)); R_RETURN(db.Commit()); } Result PtpResponder::WriteResponse(PtpResponseCode code) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); R_TRY(db.AddResponseHeader(m_request_header, code, 0)); R_RETURN(db.Commit()); } + Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write the device info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(MtpStandardVersion)); + R_TRY(db.Add(MtpVendorExtensionId)); + R_TRY(db.Add(MtpStandardVersion)); + R_TRY(db.AddString(MtpVendorExtensionDesc)); + R_TRY(db.Add(MtpFunctionalModeDefault)); + R_TRY(db.AddArray(SupportedOperationCodes, util::size(SupportedOperationCodes))); + R_TRY(db.AddArray(SupportedEventCodes, util::size(SupportedEventCodes))); + R_TRY(db.AddArray(SupportedDeviceProperties, util::size(SupportedDeviceProperties))); + R_TRY(db.AddArray(SupportedCaptureFormats, util::size(SupportedCaptureFormats))); + R_TRY(db.AddArray(SupportedPlaybackFormats, util::size(SupportedPlaybackFormats))); + R_TRY(db.AddString(MtpDeviceManufacturer)); + R_TRY(db.AddString(MtpDeviceModel)); + R_TRY(db.AddString(GetFirmwareVersion())); + R_TRY(db.AddString(GetSerialNumber())); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::OpenSession(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + /* Close, if we're already open. */ + this->ForceCloseSession(); + + /* Initialize the database. */ + m_session_open = true; + m_object_database.Initialize(m_object_heap); + + /* Create the root storages. */ + PtpObject *object; + R_TRY(m_object_database.CreateOrFindObject("", "", PtpGetObjectHandles_RootParent, std::addressof(object))); + + /* Register the root storages. */ + m_object_database.RegisterObject(object, StorageId_SdmcFs); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::CloseSession(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + this->ForceCloseSession(); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetStorageIds(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write the storage ID array. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_RETURN(db.AddArray(SupportedStorageIds, util::size(SupportedStorageIds))); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetStorageInfo(PtpDataParser &dp) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpStorageInfo storage_info(DefaultStorageInfo); + + /* Get the storage ID the client requested information for. */ + u32 storage_id; + R_TRY(dp.Read(std::addressof(storage_id))); + R_TRY(dp.Finalize()); + + /* Get the info from fs. */ + switch (storage_id) { + case StorageId_SdmcFs: + { + s64 total_space, free_space; + R_TRY(m_fs.GetTotalSpace("/", std::addressof(total_space))); + R_TRY(m_fs.GetFreeSpace("/", std::addressof(free_space))); + + storage_info.max_capacity = total_space; + storage_info.free_space_in_bytes = free_space; + storage_info.free_space_in_images = 0; + storage_info.storage_description = "SD Card"; + } + break; + default: + R_THROW(haze::ResultInvalidStorageId()); + } + + /* Write the storage info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(storage_info.storage_type)); + R_TRY(db.Add(storage_info.filesystem_type)); + R_TRY(db.Add(storage_info.access_capability)); + R_TRY(db.Add(storage_info.max_capacity)); + R_TRY(db.Add(storage_info.free_space_in_bytes)); + R_TRY(db.Add(storage_info.free_space_in_images)); + R_TRY(db.AddString(storage_info.storage_description)); + R_TRY(db.AddString(storage_info.volume_label)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectHandles(PtpDataParser &dp) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested enumeration for. */ + u32 storage_id, object_format_code, association_object_handle; + R_TRY(dp.Read(std::addressof(storage_id))); + R_TRY(dp.Read(std::addressof(object_format_code))); + R_TRY(dp.Read(std::addressof(association_object_handle))); + R_TRY(dp.Finalize()); + + /* Handle top-level requests. */ + if (storage_id == PtpGetObjectHandles_AllStorage) { + storage_id = StorageId_SdmcFs; + } + + /* Rewrite requests for enumerating storage directories. */ + if (association_object_handle == PtpGetObjectHandles_RootParent) { + association_object_handle = storage_id; + } + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(association_object_handle); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Try to read the object as a directory. */ + FsDir dir; + R_TRY(m_fs.OpenDirectory(obj->GetName(), FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles, std::addressof(dir))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseDirectory(std::addressof(dir)); }; + + /* Count how many entries are in the directory. */ + s64 entry_count = 0; + R_TRY(m_fs.GetDirectoryEntryCount(std::addressof(dir), std::addressof(entry_count))); + + /* Begin writing. */ + R_TRY(db.AddDataHeader(m_request_header, sizeof(u32) + (entry_count * sizeof(u32)))); + R_TRY(db.Add(static_cast(entry_count))); + + /* Enumerate the directory, writing results to the data builder as we progress. */ + /* TODO: How should we handle the directory contents changing during enumeration? */ + /* Is this even feasible to handle? */ + while (true) { + /* Get the next batch. */ + s64 read_count = 0; + R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, g_dir_entries)); + + /* Write to output. */ + for (s64 i = 0; i < read_count; i++) { + u32 handle; + R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), g_dir_entries[i].name, obj->GetObjectId(), std::addressof(handle))); + R_TRY(db.Add(handle)); + } + + /* If we read fewer than the batch size, we're done. */ + if (read_count < DirectoryReadSize) { + break; + } + } + + /* Flush the data response. */ + R_TRY(db.Commit()); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectInfo(PtpDataParser &dp) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested info for. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Build info about the object. */ + PtpObjectInfo object_info(DefaultObjectInfo); + + if (object_id == StorageId_SdmcFs) { + /* The SD Card directory has some special properties. */ + object_info.object_format = PtpObjectFormatCode_Association; + object_info.association_type = PtpAssociationType_GenericFolder; + object_info.filename = "SD Card"; + } else { + /* Figure out what type of object this is. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Get the size, if we are requesting info about a file. */ + s64 size = 0; + if (entry_type == FsDirEntryType_File) { + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); + } + + object_info.filename = std::strrchr(obj->GetName(), '/') + 1; + object_info.object_compressed_size = size; + object_info.parent_object = obj->GetParentId(); + + if (entry_type == FsDirEntryType_Dir) { + object_info.object_format = PtpObjectFormatCode_Association; + object_info.association_type = PtpAssociationType_GenericFolder; + } else { + object_info.object_format = PtpObjectFormatCode_Undefined; + object_info.association_type = PtpAssociationType_Undefined; + } + } + + /* Write the object info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(object_info.storage_id)); + R_TRY(db.Add(object_info.object_format)); + R_TRY(db.Add(object_info.protection_status)); + R_TRY(db.Add(object_info.object_compressed_size)); + R_TRY(db.Add(object_info.thumb_format)); + R_TRY(db.Add(object_info.thumb_compressed_size)); + R_TRY(db.Add(object_info.thumb_width)); + R_TRY(db.Add(object_info.thumb_height)); + R_TRY(db.Add(object_info.image_width)); + R_TRY(db.Add(object_info.image_height)); + R_TRY(db.Add(object_info.image_depth)); + R_TRY(db.Add(object_info.parent_object)); + R_TRY(db.Add(object_info.association_type)); + R_TRY(db.Add(object_info.association_desc)); + R_TRY(db.Add(object_info.sequence_number)); + R_TRY(db.AddString(object_info.filename)); + R_TRY(db.AddString(object_info.capture_date)); + R_TRY(db.AddString(object_info.modification_date)); + R_TRY(db.AddString(object_info.keywords)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObject(PtpDataParser &dp) { + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Get the file's size. */ + s64 size = 0; + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); + + /* Send the header and file size. */ + R_TRY(db.AddDataHeader(m_request_header, size)); + + /* Begin reading the file, writing data to the builder as we progress. */ + s64 offset = 0; + while (true) { + /* Get the next batch. */ + u64 bytes_read; + R_TRY(m_fs.ReadFile(std::addressof(file), offset, g_fs_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); + + offset += bytes_read; + + /* Write to output. */ + R_TRY(db.AddBuffer(g_fs_buffer, bytes_read)); + + /* If we read fewer bytes than the batch size, we're done. */ + if (bytes_read < FsBufferSize) { + break; + } + } + + /* Flush the data response. */ + R_TRY(db.Commit()); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::SendObjectInfo(PtpDataParser &rdp) { + /* Get the storage ID and parent object and flush the request packet. */ + u32 storage_id, parent_object; + R_TRY(rdp.Read(std::addressof(storage_id))); + R_TRY(rdp.Read(std::addressof(parent_object))); + R_TRY(rdp.Finalize()); + + PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + PtpObjectInfo info(DefaultObjectInfo); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Read in the object info. */ + R_TRY(dp.Read(std::addressof(info.storage_id))); + R_TRY(dp.Read(std::addressof(info.object_format))); + R_TRY(dp.Read(std::addressof(info.protection_status))); + R_TRY(dp.Read(std::addressof(info.object_compressed_size))); + R_TRY(dp.Read(std::addressof(info.thumb_format))); + R_TRY(dp.Read(std::addressof(info.thumb_compressed_size))); + R_TRY(dp.Read(std::addressof(info.thumb_width))); + R_TRY(dp.Read(std::addressof(info.thumb_height))); + R_TRY(dp.Read(std::addressof(info.image_width))); + R_TRY(dp.Read(std::addressof(info.image_height))); + R_TRY(dp.Read(std::addressof(info.image_depth))); + R_TRY(dp.Read(std::addressof(info.parent_object))); + R_TRY(dp.Read(std::addressof(info.association_type))); + R_TRY(dp.Read(std::addressof(info.association_desc))); + R_TRY(dp.Read(std::addressof(info.sequence_number))); + R_TRY(dp.ReadString(g_filename_str)); + R_TRY(dp.ReadString(g_capture_date_str)); + R_TRY(dp.ReadString(g_modification_date_str)); + R_TRY(dp.ReadString(g_keywords_str)); + R_TRY(dp.Finalize()); + + /* Rewrite requests for creating in storage directories. */ + if (parent_object == PtpGetObjectHandles_RootParent) { + parent_object = storage_id; + } + + /* Check if we know about the parent object. If we don't, it's an error. */ + auto * const parentobj = m_object_database.GetObjectById(parent_object); + R_UNLESS(parentobj != nullptr, haze::ResultInvalidObjectId()); + + /* Make a new object with the intended name. */ + PtpNewObjectInfo new_object_info; + new_object_info.storage_id = StorageId_SdmcFs; + new_object_info.parent_object_id = parent_object == storage_id ? 0 : parent_object; + + /* Create the object in the database. */ + PtpObject *obj; + R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), g_filename_str, parentobj->GetObjectId(), std::addressof(obj))); + + /* Ensure we maintain a clean state on failure. */ + ON_RESULT_FAILURE { m_object_database.DeleteObject(obj); }; + + /* Register the object with a new ID. */ + m_object_database.RegisterObject(obj); + new_object_info.object_id = obj->GetObjectId(); + + /* Create the object on the filesystem. */ + if (info.object_format == PtpObjectFormatCode_Association) { + R_TRY(m_fs.CreateDirectory(obj->GetName())); + m_send_object_id = 0; + } else { + R_TRY(m_fs.CreateFile(obj->GetName(), 0, 0)); + m_send_object_id = new_object_info.object_id; + } + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok, new_object_info)); + } + + Result PtpResponder::SendObject(PtpDataParser &rdp) { + /* Reset SendObject object ID on exit. */ + ON_SCOPE_EXIT { m_send_object_id = 0; }; + + R_TRY(rdp.Finalize()); + + PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(m_send_object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Truncate the file after locking for write. */ + s64 offset = 0; + R_TRY(m_fs.SetFileSize(std::addressof(file), 0)); + + /* Expand to the needed size. */ + if (data_header.length > sizeof(PtpUsbBulkContainer)) { + R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length - sizeof(PtpUsbBulkContainer))); + } + + /* Begin writing to the filesystem. */ + while (true) { + /* Read as many bytes as we can. */ + u32 bytes_received; + const Result read_res = dp.ReadBuffer(g_fs_buffer, FsBufferSize, std::addressof(bytes_received)); + + /* Write to the file. */ + R_TRY(m_fs.WriteFile(std::addressof(file), offset, g_fs_buffer, bytes_received, 0)); + + offset += bytes_received; + + /* If we received fewer bytes than the batch size, we're done. */ + if (haze::ResultEndOfTransmission::Includes(read_res)) { + break; + } + + R_TRY(read_res); + } + + /* Truncate the file to the received size. */ + R_TRY(m_fs.SetFileSize(std::addressof(file), offset)); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::DeleteObject(PtpDataParser &dp) { + /* Get the object ID and flush the request packet. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Disallow deleting the storage root. */ + R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Figure out what type of object this is. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Remove the object from the filesystem. */ + if (entry_type == FsDirEntryType_Dir) { + R_TRY(m_fs.DeleteDirectoryRecursively(obj->GetName())); + } else { + R_TRY(m_fs.DeleteFile(obj->GetName())); + } + + /* Remove the object from the database. */ + m_object_database.DeleteObject(obj); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectPropsSupported(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write information about all object properties we can support. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_RETURN(db.AddArray(SupportedObjectProperties, util::size(SupportedObjectProperties))); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectPropDesc(PtpDataParser &dp) { + PtpObjectPropertyCode property_code; + u16 object_format; + + R_TRY(dp.Read(std::addressof(property_code))); + R_TRY(dp.Read(std::addressof(object_format))); + R_TRY(dp.Finalize()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); + + /* Begin writing information about the property code. */ + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_TRY(db.Add(property_code)); + + /* Each property code corresponds to a different pattern, which contains the data type, */ + /* whether the property can be set for an object, and the default value of the property. */ + switch (property_code) { + case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: + { + R_TRY(db.Add(PtpDataTypeCode_U128)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(0)); + } + case PtpObjectPropertyCode_ObjectSize: + { + R_TRY(db.Add(PtpDataTypeCode_U64)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(0)); + } + break; + case PtpObjectPropertyCode_StorageId: + case PtpObjectPropertyCode_ParentObject: + { + R_TRY(db.Add(PtpDataTypeCode_U32)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(StorageId_SdmcFs)); + } + break; + case PtpObjectPropertyCode_ObjectFormat: + { + R_TRY(db.Add(PtpDataTypeCode_U16)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(PtpObjectFormatCode_Undefined)); + } + break; + case PtpObjectPropertyCode_ObjectFileName: + { + R_TRY(db.Add(PtpDataTypeCode_String)); + R_TRY(db.Add(PtpPropertyGetSetFlag_GetSet)); + R_TRY(db.AddString("")); + } + break; + HAZE_UNREACHABLE_DEFAULT_CASE(); + } + + /* Group code is a required part of the response, but doesn't seem to be used for anything. */ + R_TRY(db.Add(PtpPropertyGroupCode_Default)); + + /* We don't use the form flag. */ + R_TRY(db.Add(PtpPropertyFormFlag_None)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectPropValue(PtpDataParser &dp) { + u32 object_id; + PtpObjectPropertyCode property_code; + + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Read(std::addressof(property_code))); + R_TRY(dp.Finalize()); + + /* Disallow renaming the storage root. */ + R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Define helper for getting the object type. */ + const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { + R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); + }; + + /* Define helper for getting the object size. */ + const auto GetObjectSize = [&] (s64 *out_size) { + *out_size = 0; + + /* Check if this is a directory. */ + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + + /* If it is, we're done. */ + R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); + + /* Otherwise, open as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); + }; + + /* Begin writing the requested object property. */ + PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + switch (property_code) { + case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: + { + R_TRY(db.Add(object_id)); + } + break; + case PtpObjectPropertyCode_ObjectSize: + { + s64 size; + R_TRY(GetObjectSize(std::addressof(size))); + R_TRY(db.Add(size)); + } + break; + case PtpObjectPropertyCode_StorageId: + { + R_TRY(db.Add(StorageId_SdmcFs)); + } + break; + case PtpObjectPropertyCode_ParentObject: + { + R_TRY(db.Add(obj->GetParentId())); + } + break; + case PtpObjectPropertyCode_ObjectFormat: + { + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); + } + break; + case PtpObjectPropertyCode_ObjectFileName: + { + R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); + } + break; + HAZE_UNREACHABLE_DEFAULT_CASE(); + } + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::SetObjectPropValue(PtpDataParser &rdp) { + u32 object_id; + PtpObjectPropertyCode property_code; + + R_TRY(rdp.Read(std::addressof(object_id))); + R_TRY(rdp.Read(std::addressof(property_code))); + R_TRY(rdp.Finalize()); + + PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(property_code == PtpObjectPropertyCode_ObjectFileName, haze::ResultUnknownPropertyCode()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* We are reading a file name. */ + R_TRY(dp.ReadString(g_filename_str)); + R_TRY(dp.Finalize()); + + /* Ensure we can actually process the new name. */ + const bool is_empty = g_filename_str[0] == '\x00'; + const bool contains_slashes = std::strchr(g_filename_str, '/') != nullptr; + R_UNLESS(!is_empty && !contains_slashes, haze::ResultInvalidPropertyValue()); + + /* Add a new object in the database with the new name. */ + PtpObject *newobj; + { + /* Find the last path separator in the existing object name. */ + char *pathsep = std::strrchr(obj->m_name, '/'); + HAZE_ASSERT(pathsep != nullptr); + + /* Temporarily mark the path separator as null to facilitate processing. */ + *pathsep = '\x00'; + ON_SCOPE_EXIT { *pathsep = '/'; }; + + R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), g_filename_str, obj->GetParentId(), std::addressof(newobj))); + } + + { + /* Ensure we maintain a clean state on failure. */ + ON_RESULT_FAILURE { + if (!newobj->GetIsRegistered()) { + /* Only delete if the object was not registered. */ + /* Otherwise, we would remove an object that still exists. */ + m_object_database.DeleteObject(newobj); + } + }; + + /* Get the old object type. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Attempt to rename the object on the filesystem. */ + if (entry_type == FsDirEntryType_Dir) { + R_TRY(m_fs.RenameDirectory(obj->GetName(), newobj->GetName())); + } else { + R_TRY(m_fs.RenameFile(obj->GetName(), newobj->GetName())); + } + } + + /* Unregister and free the old object. */ + m_object_database.DeleteObject(obj); + + /* Register the new object. */ + m_object_database.RegisterObject(newobj, object_id); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } } diff --git a/troposphere/haze/source/ptp_responder_android_operations.cpp b/troposphere/haze/source/ptp_responder_android_operations.cpp deleted file mode 100644 index aef13011e..000000000 --- a/troposphere/haze/source/ptp_responder_android_operations.cpp +++ /dev/null @@ -1,203 +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 . - */ -#include -#include -#include -#include - -namespace haze { - - Result PtpResponder::GetPartialObject64(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID, offset, and size for the file we want to read. */ - u32 object_id, size; - u64 offset; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Read(std::addressof(offset))); - R_TRY(dp.Read(std::addressof(size))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Get the file's size. */ - s64 file_size = 0; - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(file_size))); - - /* Ensure the requested offset and size are within range. */ - R_UNLESS(offset + size > offset, haze::ResultInvalidArgument()); - R_UNLESS(static_cast(file_size) <= offset + size, haze::ResultInvalidArgument()); - - /* Send the header and data size. */ - R_TRY(db.AddDataHeader(m_request_header, size)); - - /* Begin reading the file, writing data to the builder as we progress. */ - s64 size_remaining = size; - while (true) { - /* Get the next batch. */ - u64 bytes_to_read = std::min(FsBufferSize, size_remaining); - u64 bytes_read; - - R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_to_read, FsReadOption_None, std::addressof(bytes_read))); - - size_remaining -= bytes_read; - offset += bytes_read; - - /* Write to output. */ - R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); - - /* If we read fewer bytes than the batch size, or have read enough data, we're done. */ - if (bytes_read < FsBufferSize || size_remaining == 0) { - break; - } - } - - /* Flush the data response. */ - R_TRY(db.Commit()); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::SendPartialObject(PtpDataParser &rdp) { - /* Get the object ID, offset, and size for the file we want to write. */ - u32 object_id, size; - u64 offset; - R_TRY(rdp.Read(std::addressof(object_id))); - R_TRY(rdp.Read(std::addressof(size))); - R_TRY(rdp.Read(std::addressof(offset))); - R_TRY(rdp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(m_send_object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Get the file's size. */ - s64 file_size = 0; - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(file_size))); - - /* Ensure the requested offset and size are within range. */ - R_UNLESS(offset + size > offset, haze::ResultInvalidArgument()); - R_UNLESS(static_cast(file_size) <= offset, haze::ResultInvalidArgument()); - - /* Prepare a data parser for the data we are about to receive. */ - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Begin writing to the filesystem. */ - s64 size_remaining = size; - while (true) { - /* Read as many bytes as we can. */ - u32 bytes_received; - const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); - - /* Write to the file. */ - u32 bytes_to_write = std::min(size_remaining, bytes_received); - R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_to_write, 0)); - - size_remaining -= bytes_to_write; - offset += bytes_to_write; - - /* If we received fewer bytes than the batch size, or have written enough data, we're done. */ - if (haze::ResultEndOfTransmission::Includes(read_res) || size_remaining == 0) { - break; - } - - R_TRY(read_res); - } - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::TruncateObject(PtpDataParser &dp) { - /* Get the object ID and size for the file we want to truncate. */ - u32 object_id; - u64 size; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Read(std::addressof(size))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Truncate the file. */ - R_TRY(m_fs.SetFileSize(std::addressof(file), size)); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::BeginEditObject(PtpDataParser &dp) { - /* Get the object ID we are going to begin editing. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* We don't implement transactions, so write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::EndEditObject(PtpDataParser &dp) { - /* Get the object ID we are going to finish editing. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* We don't implement transactions, so write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - -} diff --git a/troposphere/haze/source/ptp_responder_mtp_operations.cpp b/troposphere/haze/source/ptp_responder_mtp_operations.cpp deleted file mode 100644 index eea3e5f4f..000000000 --- a/troposphere/haze/source/ptp_responder_mtp_operations.cpp +++ /dev/null @@ -1,418 +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 . - */ -#include -#include -#include -#include - -namespace haze { - - Result PtpResponder::GetObjectPropsSupported(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write information about all object properties we can support. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_RETURN(db.AddArray(SupportedObjectProperties, util::size(SupportedObjectProperties))); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropDesc(PtpDataParser &dp) { - PtpObjectPropertyCode property_code; - u16 object_format; - - R_TRY(dp.Read(std::addressof(property_code))); - R_TRY(dp.Read(std::addressof(object_format))); - R_TRY(dp.Finalize()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); - - /* Begin writing information about the property code. */ - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_TRY(db.Add(property_code)); - - /* Each property code corresponds to a different pattern, which contains the data type, */ - /* whether the property can be set for an object, and the default value of the property. */ - switch (property_code) { - case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: - { - R_TRY(db.Add(PtpDataTypeCode_U128)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(0)); - } - case PtpObjectPropertyCode_ObjectSize: - { - R_TRY(db.Add(PtpDataTypeCode_U64)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(0)); - } - break; - case PtpObjectPropertyCode_StorageId: - case PtpObjectPropertyCode_ParentObject: - { - R_TRY(db.Add(PtpDataTypeCode_U32)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(StorageId_SdmcFs)); - } - break; - case PtpObjectPropertyCode_ObjectFormat: - { - R_TRY(db.Add(PtpDataTypeCode_U16)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(PtpObjectFormatCode_Undefined)); - } - break; - case PtpObjectPropertyCode_ObjectFileName: - { - R_TRY(db.Add(PtpDataTypeCode_String)); - R_TRY(db.Add(PtpPropertyGetSetFlag_GetSet)); - R_TRY(db.AddString("")); - } - break; - HAZE_UNREACHABLE_DEFAULT_CASE(); - } - - /* Group code is a required part of the response, but doesn't seem to be used for anything. */ - R_TRY(db.Add(PtpPropertyGroupCode_Default)); - - /* We don't use the form flag. */ - R_TRY(db.Add(PtpPropertyFormFlag_None)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropValue(PtpDataParser &dp) { - u32 object_id; - PtpObjectPropertyCode property_code; - - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Read(std::addressof(property_code))); - R_TRY(dp.Finalize()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Define helper for getting the object type. */ - const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { - R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); - }; - - /* Define helper for getting the object size. */ - const auto GetObjectSize = [&] (s64 *out_size) { - *out_size = 0; - - /* Check if this is a directory. */ - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - - /* If it is, we're done. */ - R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); - - /* Otherwise, open as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); - }; - - /* Begin writing the requested object property. */ - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - switch (property_code) { - case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: - { - R_TRY(db.Add(object_id)); - } - break; - case PtpObjectPropertyCode_ObjectSize: - { - s64 size; - R_TRY(GetObjectSize(std::addressof(size))); - R_TRY(db.Add(size)); - } - break; - case PtpObjectPropertyCode_StorageId: - { - R_TRY(db.Add(StorageId_SdmcFs)); - } - break; - case PtpObjectPropertyCode_ParentObject: - { - R_TRY(db.Add(obj->GetParentId())); - } - break; - case PtpObjectPropertyCode_ObjectFormat: - { - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); - } - break; - case PtpObjectPropertyCode_ObjectFileName: - { - R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); - } - break; - HAZE_UNREACHABLE_DEFAULT_CASE(); - } - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropList(PtpDataParser &dp) { - u32 object_id; - u32 object_format; - s32 property_code; - s32 group_code; - s32 depth; - - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Read(std::addressof(object_format))); - R_TRY(dp.Read(std::addressof(property_code))); - R_TRY(dp.Read(std::addressof(group_code))); - R_TRY(dp.Read(std::addressof(depth))); - R_TRY(dp.Finalize()); - - /* Ensure format is unspecified. */ - R_UNLESS(object_format == 0, haze::ResultInvalidArgument()); - - /* Ensure we have a valid property code. */ - R_UNLESS(property_code == -1 || IsSupportedObjectPropertyCode(PtpObjectPropertyCode(property_code)), haze::ResultUnknownPropertyCode()); - - /* Ensure group code is the default. */ - R_UNLESS(group_code == PtpPropertyGroupCode_Default, haze::ResultGroupSpecified()); - - /* Ensure depth is 0. */ - R_UNLESS(depth == 0, haze::ResultDepthSpecified()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Define helper for getting the object type. */ - const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { - R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); - }; - - /* Define helper for getting the object size. */ - const auto GetObjectSize = [&] (s64 *out_size) { - *out_size = 0; - - /* Check if this is a directory. */ - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - - /* If it is, we're done. */ - R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); - - /* Otherwise, open as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); - }; - - /* Define helper for determining if the property should be included. */ - const auto ShouldIncludeProperty = [&] (PtpObjectPropertyCode code) { - /* If all properties were requested, or it was the requested property, we should include the property. */ - return property_code == -1 || code == property_code; - }; - - /* Determine how many output elements we will report. */ - u32 num_output_elements = 0; - for (const auto obj_property : SupportedObjectProperties) { - if (ShouldIncludeProperty(obj_property)) { - num_output_elements++; - } - } - - /* Begin writing the requested object properties. */ - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - /* Report the number of elements. */ - R_TRY(db.Add(num_output_elements)); - - for (const auto obj_property : SupportedObjectProperties) { - if (!ShouldIncludeProperty(obj_property)) { - continue; - } - - /* Write the object handle. */ - R_TRY(db.Add(object_id)); - - /* Write the property code. */ - R_TRY(db.Add(obj_property)); - - /* Write the property value. */ - switch (obj_property) { - case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: - { - R_TRY(db.Add(PtpDataTypeCode_U128)); - R_TRY(db.Add(object_id)); - } - break; - case PtpObjectPropertyCode_ObjectSize: - { - s64 size; - R_TRY(GetObjectSize(std::addressof(size))); - R_TRY(db.Add(PtpDataTypeCode_U64)); - R_TRY(db.Add(size)); - } - break; - case PtpObjectPropertyCode_StorageId: - { - R_TRY(db.Add(PtpDataTypeCode_U32)); - R_TRY(db.Add(StorageId_SdmcFs)); - } - break; - case PtpObjectPropertyCode_ParentObject: - { - R_TRY(db.Add(PtpDataTypeCode_U32)); - R_TRY(db.Add(obj->GetParentId())); - } - break; - case PtpObjectPropertyCode_ObjectFormat: - { - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - R_TRY(db.Add(PtpDataTypeCode_U16)); - R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); - } - break; - case PtpObjectPropertyCode_ObjectFileName: - { - R_TRY(db.Add(PtpDataTypeCode_String)); - R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); - } - break; - HAZE_UNREACHABLE_DEFAULT_CASE(); - } - } - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::SetObjectPropValue(PtpDataParser &rdp) { - u32 object_id; - PtpObjectPropertyCode property_code; - - R_TRY(rdp.Read(std::addressof(object_id))); - R_TRY(rdp.Read(std::addressof(property_code))); - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(property_code == PtpObjectPropertyCode_ObjectFileName, haze::ResultUnknownPropertyCode()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* We are reading a file name. */ - R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); - R_TRY(dp.Finalize()); - - /* Ensure we can actually process the new name. */ - const bool is_empty = m_buffers->filename_string_buffer[0] == '\x00'; - const bool contains_slashes = std::strchr(m_buffers->filename_string_buffer, '/') != nullptr; - R_UNLESS(!is_empty && !contains_slashes, haze::ResultInvalidPropertyValue()); - - /* Add a new object in the database with the new name. */ - PtpObject *newobj; - { - /* Find the last path separator in the existing object name. */ - char *pathsep = std::strrchr(obj->m_name, '/'); - HAZE_ASSERT(pathsep != nullptr); - - /* Temporarily mark the path separator as null to facilitate processing. */ - *pathsep = '\x00'; - ON_SCOPE_EXIT { *pathsep = '/'; }; - - R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), m_buffers->filename_string_buffer, obj->GetParentId(), std::addressof(newobj))); - } - - { - /* Ensure we maintain a clean state on failure. */ - ON_RESULT_FAILURE { - if (!newobj->GetIsRegistered()) { - /* Only delete if the object was not registered. */ - /* Otherwise, we would remove an object that still exists. */ - m_object_database.DeleteObject(newobj); - } - }; - - /* Get the old object type. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Attempt to rename the object on the filesystem. */ - if (entry_type == FsDirEntryType_Dir) { - R_TRY(m_fs.RenameDirectory(obj->GetName(), newobj->GetName())); - } else { - R_TRY(m_fs.RenameFile(obj->GetName(), newobj->GetName())); - } - } - - /* Unregister and free the old object. */ - m_object_database.DeleteObject(obj); - - /* Register the new object. */ - m_object_database.RegisterObject(newobj, object_id); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - -} diff --git a/troposphere/haze/source/ptp_responder_ptp_operations.cpp b/troposphere/haze/source/ptp_responder_ptp_operations.cpp deleted file mode 100644 index 4213a5061..000000000 --- a/troposphere/haze/source/ptp_responder_ptp_operations.cpp +++ /dev/null @@ -1,507 +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 . - */ -#include -#include -#include -#include - -namespace haze { - - Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write the device info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(MtpStandardVersion)); - R_TRY(db.Add(MtpVendorExtensionId)); - R_TRY(db.Add(MtpStandardVersion)); - R_TRY(db.AddString(MtpVendorExtensionDesc)); - R_TRY(db.Add(MtpFunctionalModeDefault)); - R_TRY(db.AddArray(SupportedOperationCodes, util::size(SupportedOperationCodes))); - R_TRY(db.AddArray(SupportedEventCodes, util::size(SupportedEventCodes))); - R_TRY(db.AddArray(SupportedDeviceProperties, util::size(SupportedDeviceProperties))); - R_TRY(db.AddArray(SupportedCaptureFormats, util::size(SupportedCaptureFormats))); - R_TRY(db.AddArray(SupportedPlaybackFormats, util::size(SupportedPlaybackFormats))); - R_TRY(db.AddString(MtpDeviceManufacturer)); - R_TRY(db.AddString(MtpDeviceModel)); - R_TRY(db.AddString(GetFirmwareVersion())); - R_TRY(db.AddString(GetSerialNumber())); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::OpenSession(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - /* Close, if we're already open. */ - this->ForceCloseSession(); - - /* Initialize the database. */ - m_session_open = true; - m_object_database.Initialize(m_object_heap); - - /* Create the root storages. */ - PtpObject *object; - R_TRY(m_object_database.CreateOrFindObject("", "", PtpGetObjectHandles_RootParent, std::addressof(object))); - - /* Register the root storages. */ - m_object_database.RegisterObject(object, StorageId_SdmcFs); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::CloseSession(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - this->ForceCloseSession(); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetStorageIds(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write the storage ID array. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_RETURN(db.AddArray(SupportedStorageIds, util::size(SupportedStorageIds))); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetStorageInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - PtpStorageInfo storage_info(DefaultStorageInfo); - - /* Get the storage ID the client requested information for. */ - u32 storage_id; - R_TRY(dp.Read(std::addressof(storage_id))); - R_TRY(dp.Finalize()); - - /* Get the info from fs. */ - switch (storage_id) { - case StorageId_SdmcFs: - { - s64 total_space, free_space; - R_TRY(m_fs.GetTotalSpace("/", std::addressof(total_space))); - R_TRY(m_fs.GetFreeSpace("/", std::addressof(free_space))); - - storage_info.max_capacity = total_space; - storage_info.free_space_in_bytes = free_space; - storage_info.free_space_in_images = 0; - storage_info.storage_description = "SD Card"; - } - break; - default: - R_THROW(haze::ResultInvalidStorageId()); - } - - /* Write the storage info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(storage_info.storage_type)); - R_TRY(db.Add(storage_info.filesystem_type)); - R_TRY(db.Add(storage_info.access_capability)); - R_TRY(db.Add(storage_info.max_capacity)); - R_TRY(db.Add(storage_info.free_space_in_bytes)); - R_TRY(db.Add(storage_info.free_space_in_images)); - R_TRY(db.AddString(storage_info.storage_description)); - R_TRY(db.AddString(storage_info.volume_label)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectHandles(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested enumeration for. */ - u32 storage_id, object_format_code, association_object_handle; - R_TRY(dp.Read(std::addressof(storage_id))); - R_TRY(dp.Read(std::addressof(object_format_code))); - R_TRY(dp.Read(std::addressof(association_object_handle))); - R_TRY(dp.Finalize()); - - /* Handle top-level requests. */ - if (storage_id == PtpGetObjectHandles_AllStorage) { - storage_id = StorageId_SdmcFs; - } - - /* Rewrite requests for enumerating storage directories. */ - if (association_object_handle == PtpGetObjectHandles_RootParent) { - association_object_handle = storage_id; - } - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(association_object_handle); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Try to read the object as a directory. */ - FsDir dir; - R_TRY(m_fs.OpenDirectory(obj->GetName(), FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles, std::addressof(dir))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseDirectory(std::addressof(dir)); }; - - /* Count how many entries are in the directory. */ - s64 entry_count = 0; - R_TRY(m_fs.GetDirectoryEntryCount(std::addressof(dir), std::addressof(entry_count))); - - /* Begin writing. */ - R_TRY(db.AddDataHeader(m_request_header, sizeof(u32) + (entry_count * sizeof(u32)))); - R_TRY(db.Add(static_cast(entry_count))); - - /* Enumerate the directory, writing results to the data builder as we progress. */ - /* TODO: How should we handle the directory contents changing during enumeration? */ - /* Is this even feasible to handle? */ - while (true) { - /* Get the next batch. */ - s64 read_count = 0; - R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, m_buffers->file_system_entry_buffer)); - - /* Write to output. */ - for (s64 i = 0; i < read_count; i++) { - const char *name = m_buffers->file_system_entry_buffer[i].name; - u32 handle; - - R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), name, obj->GetObjectId(), std::addressof(handle))); - R_TRY(db.Add(handle)); - } - - /* If we read fewer than the batch size, we're done. */ - if (read_count < DirectoryReadSize) { - break; - } - } - - /* Flush the data response. */ - R_TRY(db.Commit()); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested info for. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Build info about the object. */ - PtpObjectInfo object_info(DefaultObjectInfo); - - if (object_id == StorageId_SdmcFs) { - /* The SD Card directory has some special properties. */ - object_info.object_format = PtpObjectFormatCode_Association; - object_info.association_type = PtpAssociationType_GenericFolder; - object_info.filename = "SD Card"; - } else { - /* Figure out what type of object this is. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Get the size, if we are requesting info about a file. */ - s64 size = 0; - if (entry_type == FsDirEntryType_File) { - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); - } - - object_info.filename = std::strrchr(obj->GetName(), '/') + 1; - object_info.object_compressed_size = size; - object_info.parent_object = obj->GetParentId(); - - if (entry_type == FsDirEntryType_Dir) { - object_info.object_format = PtpObjectFormatCode_Association; - object_info.association_type = PtpAssociationType_GenericFolder; - } else { - object_info.object_format = PtpObjectFormatCode_Undefined; - object_info.association_type = PtpAssociationType_Undefined; - } - } - - /* Write the object info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(object_info.storage_id)); - R_TRY(db.Add(object_info.object_format)); - R_TRY(db.Add(object_info.protection_status)); - R_TRY(db.Add(object_info.object_compressed_size)); - R_TRY(db.Add(object_info.thumb_format)); - R_TRY(db.Add(object_info.thumb_compressed_size)); - R_TRY(db.Add(object_info.thumb_width)); - R_TRY(db.Add(object_info.thumb_height)); - R_TRY(db.Add(object_info.image_width)); - R_TRY(db.Add(object_info.image_height)); - R_TRY(db.Add(object_info.image_depth)); - R_TRY(db.Add(object_info.parent_object)); - R_TRY(db.Add(object_info.association_type)); - R_TRY(db.Add(object_info.association_desc)); - R_TRY(db.Add(object_info.sequence_number)); - R_TRY(db.AddString(object_info.filename)); - R_TRY(db.AddString(object_info.capture_date)); - R_TRY(db.AddString(object_info.modification_date)); - R_TRY(db.AddString(object_info.keywords)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObject(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Get the file's size. */ - s64 size = 0; - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); - - /* Send the header and file size. */ - R_TRY(db.AddDataHeader(m_request_header, size)); - - /* Begin reading the file, writing data to the builder as we progress. */ - s64 offset = 0; - while (true) { - /* Get the next batch. */ - u64 bytes_read; - R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); - - offset += bytes_read; - - /* Write to output. */ - R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); - - /* If we read fewer bytes than the batch size, we're done. */ - if (bytes_read < FsBufferSize) { - break; - } - } - - /* Flush the data response. */ - R_TRY(db.Commit()); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::SendObjectInfo(PtpDataParser &rdp) { - /* Get the storage ID and parent object and flush the request packet. */ - u32 storage_id, parent_object; - R_TRY(rdp.Read(std::addressof(storage_id))); - R_TRY(rdp.Read(std::addressof(parent_object))); - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - PtpObjectInfo info(DefaultObjectInfo); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Read in the object info. */ - R_TRY(dp.Read(std::addressof(info.storage_id))); - R_TRY(dp.Read(std::addressof(info.object_format))); - R_TRY(dp.Read(std::addressof(info.protection_status))); - R_TRY(dp.Read(std::addressof(info.object_compressed_size))); - R_TRY(dp.Read(std::addressof(info.thumb_format))); - R_TRY(dp.Read(std::addressof(info.thumb_compressed_size))); - R_TRY(dp.Read(std::addressof(info.thumb_width))); - R_TRY(dp.Read(std::addressof(info.thumb_height))); - R_TRY(dp.Read(std::addressof(info.image_width))); - R_TRY(dp.Read(std::addressof(info.image_height))); - R_TRY(dp.Read(std::addressof(info.image_depth))); - R_TRY(dp.Read(std::addressof(info.parent_object))); - R_TRY(dp.Read(std::addressof(info.association_type))); - R_TRY(dp.Read(std::addressof(info.association_desc))); - R_TRY(dp.Read(std::addressof(info.sequence_number))); - R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); - R_TRY(dp.ReadString(m_buffers->capture_date_string_buffer)); - R_TRY(dp.ReadString(m_buffers->modification_date_string_buffer)); - R_TRY(dp.ReadString(m_buffers->keywords_string_buffer)); - R_TRY(dp.Finalize()); - - /* Rewrite requests for creating in storage directories. */ - if (parent_object == PtpGetObjectHandles_RootParent) { - parent_object = storage_id; - } - - /* Check if we know about the parent object. If we don't, it's an error. */ - auto * const parentobj = m_object_database.GetObjectById(parent_object); - R_UNLESS(parentobj != nullptr, haze::ResultInvalidObjectId()); - - /* Make a new object with the intended name. */ - PtpNewObjectInfo new_object_info; - new_object_info.storage_id = StorageId_SdmcFs; - new_object_info.parent_object_id = parent_object == storage_id ? 0 : parent_object; - - /* Create the object in the database. */ - PtpObject *obj; - R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), m_buffers->filename_string_buffer, parentobj->GetObjectId(), std::addressof(obj))); - - /* Ensure we maintain a clean state on failure. */ - ON_RESULT_FAILURE { m_object_database.DeleteObject(obj); }; - - /* Register the object with a new ID. */ - m_object_database.RegisterObject(obj); - new_object_info.object_id = obj->GetObjectId(); - - /* Create the object on the filesystem. */ - if (info.object_format == PtpObjectFormatCode_Association) { - R_TRY(m_fs.CreateDirectory(obj->GetName())); - m_send_object_id = 0; - } else { - R_TRY(m_fs.CreateFile(obj->GetName(), 0, 0)); - m_send_object_id = new_object_info.object_id; - } - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok, new_object_info)); - } - - Result PtpResponder::SendObject(PtpDataParser &rdp) { - /* Reset SendObject object ID on exit. */ - ON_SCOPE_EXIT { m_send_object_id = 0; }; - - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(m_send_object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Truncate the file after locking for write. */ - s64 offset = 0; - R_TRY(m_fs.SetFileSize(std::addressof(file), 0)); - - /* Expand to the needed size. */ - if (data_header.length > sizeof(PtpUsbBulkContainer)) { - R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length - sizeof(PtpUsbBulkContainer))); - } - - /* Begin writing to the filesystem. */ - while (true) { - /* Read as many bytes as we can. */ - u32 bytes_received; - const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); - - /* Write to the file. */ - R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_received, 0)); - - offset += bytes_received; - - /* If we received fewer bytes than the batch size, we're done. */ - if (haze::ResultEndOfTransmission::Includes(read_res)) { - break; - } - - R_TRY(read_res); - } - - /* Truncate the file to the received size. */ - R_TRY(m_fs.SetFileSize(std::addressof(file), offset)); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::DeleteObject(PtpDataParser &dp) { - /* Get the object ID and flush the request packet. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Disallow deleting the storage root. */ - R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Figure out what type of object this is. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Remove the object from the filesystem. */ - if (entry_type == FsDirEntryType_Dir) { - R_TRY(m_fs.DeleteDirectoryRecursively(obj->GetName())); - } else { - R_TRY(m_fs.DeleteFile(obj->GetName())); - } - - /* Remove the object from the database. */ - m_object_database.DeleteObject(obj); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - -} diff --git a/troposphere/haze/source/usb_session.cpp b/troposphere/haze/source/usb_session.cpp index 581edf199..3c0244f5f 100644 --- a/troposphere/haze/source/usb_session.cpp +++ b/troposphere/haze/source/usb_session.cpp @@ -191,7 +191,6 @@ namespace haze { R_TRY(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, std::addressof(device_descriptor))); device_descriptor.bcdUSB = 0x0300; - device_descriptor.bMaxPacketSize0 = 0x09; R_TRY(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Super, std::addressof(device_descriptor))); /* Binary Object Store */ diff --git a/utilities/erpt.py b/utilities/erpt.py index a69e6e915..3920a3d98 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -61,9 +61,6 @@ else: DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT, DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, DT_BIND_NOW, DT_INIT_ARRAY, DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = iter_range(31) - -DT_RELRSZ, DT_RELR, DT_RELRENT = 0x23, 0x24, 0x25 - DT_GNU_HASH = 0x6ffffef5 DT_VERSYM = 0x6ffffff0 DT_RELACOUNT = 0x6ffffff9 @@ -87,8 +84,6 @@ R_ARM_GLOB_DAT = 21 R_ARM_JUMP_SLOT = 22 R_ARM_RELATIVE = 23 -R_FAKE_RELR = -1 - R_AARCH64_ABS64 = 257 R_AARCH64_GLOB_DAT = 1025 R_AARCH64_JUMP_SLOT = 1026 @@ -236,19 +231,6 @@ CATEGORIES = { 137 : 'BuiltInWirelessOUIInfo', 138 : 'WirelessAPOUIInfo', 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 = { @@ -276,7 +258,15 @@ FIELD_FLAGS = { } def get_full(nxo): - full = nxo.full[:] + full = nxo.text[0] + if nxo.ro[2] >= len(full): + full += b'\x00' * (nxo.ro[2] - len(full)) + else: + full = full[:nxo.ro[2]] + full += nxo.ro[0] + if nxo.data[2] > len(full): + full += b'\x00' * (nxo.data[2] - len(full)) + full += nxo.data[0] undef_count = 0 for s in nxo.symbols: @@ -313,8 +303,6 @@ def get_full(nxo): return z[:target] + pk(' compressed_size + compressed = compressed[len(compressed) - compressed_size:] + if not (compressed_size + uncompressed_addl_size): + return b'' + compressed = bytes_to_list(compressed) + decompressed = bytes_to_list(decompressed) + index = compressed_size - init_index + outindex = decompressed_size + while outindex > 0: + index -= 1 + control = compressed[index] + for i in iter_range(8): + if control & 0x80: + if index < 2: + raise ValueError('Compression out of bounds!') + index -= 2 + segmentoffset = compressed[index] | (compressed[index+1] << 8) + segmentsize = ((segmentoffset >> 12) & 0xF) + 3 + segmentoffset &= 0x0FFF + segmentoffset += 2 + if outindex < segmentsize: + raise ValueError('Compression out of bounds!') + for j in iter_range(segmentsize): + if outindex + segmentoffset >= decompressed_size: + raise ValueError('Compression out of bounds!') + data = decompressed[outindex+segmentoffset] + outindex -= 1 + decompressed[outindex] = data + else: + if outindex < 1: + raise ValueError('Compression out of bounds!') + outindex -= 1 + index -= 1 + decompressed[outindex] = compressed[index] + control <<= 1 + control &= 0xFF + if not outindex: + break + return list_to_bytes(decompressed) class BinFile(object): def __init__(self, li): @@ -48,19 +96,11 @@ class BinFile(object): return out[0] return out elif arg is None: - return self.read_to_end() + return self._f.read() else: out = self._f.read(arg) - if isinstance(arg, (int,long)) and len(out) != arg: - pass #print 'warning: read of %d bytes got %d bytes' % (arg, len(out)) return out - def read_to_end(self): - return self.read(self.size()-self.tell()) - - def size(self): - return get_file_size(self._f) - def read_from(self, arg, offset): old = self.tell() try: @@ -73,9 +113,6 @@ class BinFile(object): def seek(self, off): self._f.seek(off) - def skip(self, dist): - self.seek(self.tell()+dist) - def close(self): self._f.close() @@ -86,10 +123,7 @@ class BinFile(object): (DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT, DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, DT_BIND_NOW, DT_INIT_ARRAY, - DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = xrange(31) - -DT_RELRSZ, DT_RELR, DT_RELRENT = 0x23, 0x24, 0x25 - + DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = iter_range(31) DT_GNU_HASH = 0x6ffffef5 DT_VERSYM = 0x6ffffff0 DT_RELACOUNT = 0x6ffffff9 @@ -113,8 +147,6 @@ R_ARM_GLOB_DAT = 21 R_ARM_JUMP_SLOT = 22 R_ARM_RELATIVE = 23 -R_FAKE_RELR = -1 - R_AARCH64_ABS64 = 257 R_AARCH64_GLOB_DAT = 1025 R_AARCH64_JUMP_SLOT = 1026 @@ -172,7 +204,6 @@ def suffixed_name(name, suffix): class SegmentBuilder(object): def __init__(self): self.segments = [] - self._sections = [] def add_segment(self, start, size, name, kind): r = Range(start, size) @@ -182,24 +213,19 @@ class SegmentBuilder(object): def add_section(self, name, start, end=None, size=None): assert end is None or size is None + if size == 0: + return if size is None: size = end-start - if size > 0: - #assert size > 0 - r = Range(start, size) - self._sections.append((r, name)) - - def _add_sections_to_segments(self): - for r, name in self._sections: - for i in self.segments: - if i.range.includes(r): - i.add_section(Section(r, name)) - break - else: - assert False, 'no containing segment for %r' % (name,) + assert size > 0 + r = Range(start, size) + for i in self.segments: + if i.range.includes(r): + i.add_section(Section(r, name)) + return + assert False, "no containing segment for %r" % (name,) def flatten(self): - self._add_sections_to_segments() self.segments.sort(key=lambda s: s.range.start) parts = [] for segment in self.segments: @@ -237,14 +263,40 @@ class ElfSym(object): class NxoFileBase(object): - def __init__(self, f, segment_data=None): + # segment = (content, file offset, vaddr, vsize) + def __init__(self, text, ro, data, bsssize): + self.text = text + self.ro = ro + self.data = data + self.bsssize = bsssize + self.textoff = text[2] + self.textsize = text[3] + self.rodataoff = ro[2] + self.rodatasize = ro[3] + self.dataoff = data[2] + flatsize = data[2] + data[3] + + full = text[0] + if ro[2] >= len(full): + full += b'\x00' * (ro[2] - len(full)) + else: + print('truncating .text?') + full = full[:ro[2]] + full += ro[0] + if data[2] > len(full): + full += b'\x00' * (data[2] - len(full)) + else: + print('truncating .rodata?') + full += data[0] + f = BinFile(BytesIO(full)) + self.binfile = f # read MOD self.modoff = f.read_from('I', 4) f.seek(self.modoff) - if f.read('4s') != 'MOD0': + if f.read('4s') != b'MOD0': raise NxoException('invalid MOD0 magic') self.dynamicoff = self.modoff + f.read('i') @@ -255,7 +307,23 @@ class NxoFileBase(object): self.moduleoff = self.modoff + f.read('i') - builder = SegmentBuilder() + self.datasize = self.bssoff - self.dataoff + self.bsssize = self.bssend - self.bssoff + + self.isLibnx = False + if f.read('4s') == 'LNY0': + self.isLibnx = True + self.libnx_got_start = self.modoff + f.read('i') + self.libnx_got_end = self.modoff + f.read('i') + + self.segment_builder = builder = SegmentBuilder() + for off,sz,name,kind in [ + (self.textoff, self.textsize, ".text", "CODE"), + (self.rodataoff, self.rodatasize, ".rodata", "CONST"), + (self.dataoff, self.datasize, ".data", "DATA"), + (self.bssoff, self.bsssize, ".bss", "BSS"), + ]: + builder.add_segment(off, sz, name, kind) # read dynamic self.armv7 = (f.read_from('Q', self.dynamicoff) > 0xFFFFFFFF or f.read_from('Q', self.dynamicoff+0x10) > 0xFFFFFFFF) @@ -265,7 +333,7 @@ class NxoFileBase(object): self.dynamic = dynamic = {} for i in MULTIPLE_DTS: dynamic[i] = [] - for i in xrange((f.size() - self.dynamicoff) / 0x10): + for i in iter_range((flatsize - self.dynamicoff) // 0x10): tag, val = f.read('II' if self.armv7 else 'QQ') if tag == DT_NULL: break @@ -273,17 +341,15 @@ class NxoFileBase(object): dynamic[tag].append(val) else: dynamic[tag] = val - self.dynamicsize = f.tell() - self.dynamicoff - builder.add_section('.dynamic', self.dynamicoff, end=self.dynamicoff + self.dynamicsize) - builder.add_section('.eh_frame_hdr', self.unwindoff, end=self.unwindend) + builder.add_section('.dynamic', self.dynamicoff, end=f.tell()) # read .dynstr if DT_STRTAB in dynamic and DT_STRSZ in dynamic: f.seek(dynamic[DT_STRTAB]) self.dynstr = f.read(dynamic[DT_STRSZ]) else: - self.dynstr = '\0' - print 'warning: no dynstr' + self.dynstr = b'\x00' + print('warning: no dynstr') for startkey, szkey, name in [ (DT_STRTAB, DT_STRSZ, '.dynstr'), @@ -291,117 +357,40 @@ class NxoFileBase(object): (DT_FINI_ARRAY, DT_FINI_ARRAYSZ, '.fini_array'), (DT_RELA, DT_RELASZ, '.rela.dyn'), (DT_REL, DT_RELSZ, '.rel.dyn'), - (DT_RELR, DT_RELRSZ, '.relr.dyn'), (DT_JMPREL, DT_PLTRELSZ, ('.rel.plt' if self.armv7 else '.rela.plt')), ]: if startkey in dynamic and szkey in dynamic: builder.add_section(name, dynamic[startkey], size=dynamic[szkey]) - # TODO - #build_id = content.find('\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00') - #if build_id >= 0: - # builder.add_section('.note.gnu.build-id', build_id, size=0x24) - #else: - # build_id = content.index('\x04\x00\x00\x00\x10\x00\x00\x00\x03\x00\x00\x00GNU\x00') - # if build_id >= 0: - # builder.add_section('.note.gnu.build-id', build_id, size=0x20) - - if DT_HASH in dynamic: - hash_start = dynamic[DT_HASH] - f.seek(hash_start) - nbucket, nchain = f.read('II') - f.skip(nbucket * 4) - f.skip(nchain * 4) - hash_end = f.tell() - builder.add_section('.hash', hash_start, end=hash_end) - - if DT_GNU_HASH in dynamic: - gnuhash_start = dynamic[DT_GNU_HASH] - f.seek(gnuhash_start) - nbuckets, symoffset, bloom_size, bloom_shift = f.read('IIII') - f.skip(bloom_size * self.offsize) - buckets = [f.read('I') for i in range(nbuckets)] - - max_symix = max(buckets) if buckets else 0 - if max_symix >= symoffset: - f.skip((max_symix - symoffset) * 4) - while (f.read('I') & 1) == 0: - pass - gnuhash_end = f.tell() - builder.add_section('.gnu.hash', gnuhash_start, end=gnuhash_end) - self.needed = [self.get_dynstr(i) for i in self.dynamic[DT_NEEDED]] # load .dynsym self.symbols = symbols = [] - f.seek(dynamic[DT_SYMTAB]) - while True: - if dynamic[DT_SYMTAB] < dynamic[DT_STRTAB] and f.tell() >= dynamic[DT_STRTAB]: - break - if self.armv7: - st_name, st_value, st_size, st_info, st_other, st_shndx = f.read('IIIBBH') - else: - st_name, st_info, st_other, st_shndx, st_value, st_size = f.read('IBBHQQ') - if st_name > len(self.dynstr): - break - symbols.append(ElfSym(self.get_dynstr(st_name), st_info, st_other, st_shndx, st_value, st_size)) - builder.add_section('.dynsym', dynamic[DT_SYMTAB], end=f.tell()) + if DT_SYMTAB in dynamic and DT_STRTAB in dynamic: + f.seek(dynamic[DT_SYMTAB]) + while True: + if dynamic[DT_SYMTAB] < dynamic[DT_STRTAB] and f.tell() >= dynamic[DT_STRTAB]: + break + if self.armv7: + st_name, st_value, st_size, st_info, st_other, st_shndx = f.read('IIIBBH') + else: + st_name, st_info, st_other, st_shndx, st_value, st_size = f.read('IBBHQQ') + if st_name > len(self.dynstr): + break + symbols.append(ElfSym(self.get_dynstr(st_name), st_info, st_other, st_shndx, st_value, st_size)) + builder.add_section('.dynsym', dynamic[DT_SYMTAB], end=f.tell()) self.plt_entries = [] self.relocations = [] locations = set() - if DT_REL in dynamic: + plt_got_end = None + if DT_REL in dynamic and DT_RELSZ in dynamic: locations |= self.process_relocations(f, symbols, dynamic[DT_REL], dynamic[DT_RELSZ]) - if DT_RELA in dynamic: + if DT_RELA in dynamic and DT_RELASZ in dynamic: locations |= self.process_relocations(f, symbols, dynamic[DT_RELA], dynamic[DT_RELASZ]) - if DT_RELR in dynamic: - locations |= self.process_relocations_relr(f, dynamic[DT_RELR], dynamic[DT_RELRSZ]) - - if segment_data is None: - # infer segment info - rloc_guess = (dynamic[DT_REL if DT_REL in dynamic else DT_RELA] & ~0xFFF) - dloc_guess = (min(i for i in locations if i != 0) & ~0xFFF) - dloc_guess2 = None - modoff = f.read_from('I', 4) - if self.modoff != 8: - search_start = (self.modoff + 0xFFF) & ~0xFFF - for i in range(search_start, f.size(), 0x1000): - count = 0 - for j in range(4, 0x1000, 4): - if f.read_from('I', i - j) != 0: - break - count += 1 - if count > 6: - dloc_guess2 = i - break - if dloc_guess2 is not None and dloc_guess2 < dloc_guess: - dloc_guess = dloc_guess2 - - if segment_data: - tloc, tsize, rloc, rsize, dloc, dsize = segment_data - assert rloc_guess == rloc - assert dloc_guess == dloc - - self.textoff = 0 - self.textsize = rloc_guess - self.rodataoff = rloc_guess - self.rodatasize = dloc_guess - rloc_guess - self.dataoff = dloc_guess - else: - tloc, tsize, rloc, rsize, dloc, dsize = segment_data - self.textoff = tloc - self.textsize = tsize - self.rodataoff = rloc - self.rodatasize = rsize - self.dataoff = dloc - - self.datasize = self.bssoff - self.dataoff - self.bsssize = self.bssend - self.bssoff - - plt_got_end = None - if DT_JMPREL in dynamic: + if DT_JMPREL in dynamic and DT_PLTRELSZ in dynamic: pltlocations = self.process_relocations(f, symbols, dynamic[DT_JMPREL], dynamic[DT_PLTRELSZ]) locations |= pltlocations @@ -430,94 +419,32 @@ class NxoFileBase(object): target = paddr + poff if plt_got_start <= target < plt_got_end: self.plt_entries.append((off, target)) - if len(self.plt_entries) > 0: - builder.add_section('.plt', min(self.plt_entries)[0], end=max(self.plt_entries)[0] + 0x10) + builder.add_section('.plt', min(self.plt_entries)[0], end=max(self.plt_entries)[0] + 0x10) - # try to find the ".got" which should follow the ".got.plt" - good = False - got_start = (plt_got_end if plt_got_end is not None else self.dynamicoff + self.dynamicsize) - got_end = self.offsize + got_start - while (got_end in locations or (plt_got_end is None and got_end < dynamic[DT_INIT_ARRAY])) and (DT_INIT_ARRAY not in dynamic or got_end < dynamic[DT_INIT_ARRAY] or dynamic[DT_INIT_ARRAY] < got_start): - good = True - got_end += self.offsize - #print 'got_start got_end %X %X %s %X' % (got_start, got_end, str(got_end in locations), dynamic[DT_INIT_ARRAY]) + # try to find the ".got" which should follow the ".got.plt" + if not self.isLibnx: + if plt_got_end is not None: + good = False + got_end = plt_got_end + self.offsize + while got_end in locations and (DT_INIT_ARRAY not in dynamic or got_end < dynamic[DT_INIT_ARRAY]): + good = True + got_end += self.offsize - if good: - self.got_start = got_start - self.got_end = got_end - builder.add_section('.got', self.got_start, end=self.got_end) - - self.eh_table = [] - if not self.armv7: - f.seek(self.unwindoff) - version, eh_frame_ptr_enc, fde_count_enc, table_enc = f.read('BBBB') - if not any(i == 0xff for i in (eh_frame_ptr_enc, fde_count_enc, table_enc)): # DW_EH_PE_omit - #assert eh_frame_ptr_enc == 0x1B # DW_EH_PE_pcrel | DW_EH_PE_sdata4 - #assert fde_count_enc == 0x03 # DW_EH_PE_absptr | DW_EH_PE_udata4 - #assert table_enc == 0x3B # DW_EH_PE_datarel | DW_EH_PE_sdata4 - if eh_frame_ptr_enc == 0x1B and fde_count_enc == 0x03 and table_enc == 0x3B: - base_offset = f.tell() - eh_frame = base_offset + f.read('i') - - fde_count = f.read('I') - #assert 8 * fde_count == self.unwindend - f.tell() - if 8 * fde_count == self.unwindend - f.tell(): - for i in range(fde_count): - pc = self.unwindoff + f.read('i') - entry = self.unwindoff + f.read('i') - self.eh_table.append((pc, entry)) - - # TODO: we miss the last one, but better than nothing - last_entry = sorted(self.eh_table, key=lambda x: x[1])[-1][1] - builder.add_section('.eh_frame', eh_frame, end=last_entry) - - - for off,sz,name,kind in [ - (self.textoff, self.textsize, '.text', 'CODE'), - (self.rodataoff, self.rodatasize, '.rodata', 'CONST'), - (self.dataoff, self.datasize, '.data', 'DATA'), - (self.bssoff, self.bsssize, '.bss', 'BSS'), - ]: - builder.add_segment(off, sz, name, kind) + if good: + builder.add_section('.got', plt_got_end, end=got_end) + if self.isLibnx: + builder.add_section('.got', self.libnx_got_start, end=self.libnx_got_end) self.sections = [] for start, end, name, kind in builder.flatten(): self.sections.append((start, end, name, kind)) - self._addr_to_name = None - self._plt_lookup = None - - @property - def addr_to_name(self): - if self._addr_to_name is None: - d = {} - for sym in self.symbols: - if sym.shndx: - d[sym.value] = sym.name - self._addr_to_name = d - return self._addr_to_name - - @property - def plt_lookup(self): - if self._plt_lookup is None: - # generate lookups for .plt call redirection - got_value_lookup = {} - for offset, r_type, sym, addend in self.relocations: - if r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64) and addend == 0 and sym.shndx: - got_value_lookup[offset] = sym.value - - self._plt_lookup = {} - for func, target in self.plt_entries: - if target in got_value_lookup: - self._plt_lookup[func] = got_value_lookup[target] - - return self._plt_lookup def process_relocations(self, f, symbols, offset, size): locations = set() f.seek(offset) relocsize = 8 if self.armv7 else 0x18 - for i in xrange(size / relocsize): + for i in iter_range(size // relocsize): # NOTE: currently assumes all armv7 relocs have no addends, # and all 64-bit ones do. if self.armv7: @@ -537,64 +464,15 @@ class NxoFileBase(object): self.relocations.append((offset, r_type, sym, addend)) return locations - def process_relocations_relr(self, f, offset, size): - locations = set() - f.seek(offset) - relocsize = 8 - for i in xrange(size / relocsize): - entry = f.read('Q') - if entry & 1: - entry >>= 1 - i = 0 - while i < (relocsize * 8) - 1: - if entry & (1 << i): - locations.add(where + i * relocsize) - self.relocations.append((where + i * relocsize, R_FAKE_RELR, None, 0)) - i += 1 - where += relocsize * ((relocsize * 8) - 1) - else: - # Where - where = entry - locations.add(where) - self.relocations.append((where, R_FAKE_RELR, None, 0)) - where += relocsize - return locations - def get_dynstr(self, o): - return self.dynstr[o:self.dynstr.index('\0', o)] + return ascii_string(self.dynstr[o:self.dynstr.index(b'\x00', o)]) - def get_path_or_name(self): - path = None - for off, end, name, class_ in self.sections: - if name == '.rodata' and end-off < 0x1000 and end-off > 8: - id_ = self.binfile.read_from(end-off, off) - length = struct.unpack_from('= len(full): - full += '\0' * (rloc - len(full)) - else: - print 'truncating?' - full = full[:rloc] - full += ro - if dloc >= len(full): - full += '\0' * (dloc - len(full)) - else: - print 'truncating?' - full = full[:dloc] - full += data - self.full = full - - super(NsoFile, self).__init__(BinFile(StringIO(full)), (tloc, tsize, rloc, rsize, dloc, dsize)) + super(NsoFile, self).__init__(text, ro, data, bsssize) class NroFile(NxoFileBase): def __init__(self, fileobj): f = BinFile(fileobj) - if f.read_from('4s', 0x10) != 'NRO0': + if f.read_from('4s', 0x10) != b'NRO0': raise NxoException('Invalid NRO magic') f.seek(0x20) @@ -640,61 +504,19 @@ class NroFile(NxoFileBase): tloc, tsize = f.read('II') rloc, rsize = f.read('II') dloc, dsize = f.read('II') + bsssize = f.read_from('I', 0x28) - # copy f, since all other formats allow the original file to be closed - f.seek(0) - full = f.read(f.size()) + text = (f.read_from(tsize, tloc), tloc, tloc, tsize) + ro = (f.read_from(rsize, rloc), rloc, rloc, rsize) + data = (f.read_from(dsize, dloc), dloc, dloc, dsize) - filecopy = BinFile(StringIO(full)) - super(NroFile, self).__init__(filecopy, (tloc, tsize, rloc, rsize, dloc, dsize)) - -def kip1_blz_decompress(compressed): - compressed_size, init_index, uncompressed_addl_size = struct.unpack(' 0: - cmp_ofs -= 1 - control = decompressed[cmp_start + cmp_ofs] - for i in xrange(8): - if control & 0x80: - if cmp_ofs < 2 - cmp_start: - raise ValueError('Compression out of bounds!') - cmp_ofs -= 2 - segmentoffset = decompressed[cmp_start + cmp_ofs] | (decompressed[cmp_start + cmp_ofs + 1] << 8) - segmentsize = ((segmentoffset >> 12) & 0xF) + 3 - segmentoffset &= 0x0FFF - segmentoffset += 2 - if out_ofs < segmentsize - cmp_start: - raise ValueError('Compression out of bounds!') - for j in xrange(segmentsize): - if out_ofs + segmentoffset >= decompressed_size: - raise ValueError('Compression out of bounds!') - data = decompressed[cmp_start + out_ofs + segmentoffset] - out_ofs -= 1 - decompressed[cmp_start + out_ofs] = data - else: - if out_ofs < 1 - cmp_start: - raise ValueError('Compression out of bounds!') - out_ofs -= 1 - cmp_ofs -= 1 - decompressed[cmp_start + out_ofs] = decompressed[cmp_start + cmp_ofs] - control <<= 1 - control &= 0xFF - if not out_ofs: - break - return ''.join(map(chr, decompressed)) + super(NroFile, self).__init__(text, ro, data, bsssize) class KipFile(NxoFileBase): def __init__(self, fileobj): f = BinFile(fileobj) - if f.read_from('4s', 0) != 'KIP1': + if f.read_from('4s', 0) != b'KIP1': raise NxoException('Invalid KIP magic') flags = f.read_from('b', 0x1F) @@ -707,72 +529,33 @@ class KipFile(NxoFileBase): roff = toff + tfilesize doff = roff + rfilesize - bsssize = f.read_from('I', 0x18) + bsssize = f.read_from('I', 0x54) + print('bss size 0x%x' % bsssize) + print('load segments') + text = (kip1_blz_decompress(f.read_from(tfilesize, toff)), None, tloc, tsize) if flags & 1 else (f.read_from(tfilesize, toff), toff, tloc, tsize) + ro = (kip1_blz_decompress(f.read_from(rfilesize, roff)), None, rloc, rsize) if flags & 2 else (f.read_from(rfilesize, roff), roff, rloc, rsize) + data = (kip1_blz_decompress(f.read_from(dfilesize, doff)), None, dloc, dsize) if flags & 4 else (f.read_from(dfilesize, doff), doff, dloc, dsize) - text = kip1_blz_decompress(str(f.read_from(tfilesize, toff))) if flags & 1 else f.read_from(tfilesize, toff) - ro = kip1_blz_decompress(str(f.read_from(rfilesize, roff))) if flags & 2 else f.read_from(rfilesize, roff) - data = kip1_blz_decompress(str(f.read_from(dfilesize, doff))) if flags & 4 else f.read_from(dfilesize, doff) + super(KipFile, self).__init__(text, ro, data, bsssize) - full = text - if rloc >= len(full): - full += '\0' * (rloc - len(full)) - else: - print 'truncating?' - full = full[:rloc] - full += ro - if dloc >= len(full): - full += '\0' * (dloc - len(full)) - else: - print 'truncating?' - full = full[:dloc] - full += data - - super(KipFile, self).__init__(BinFile(StringIO(full)), (tloc, tsize, rloc, rsize, dloc, dsize)) - -class MemoryDumpFile(NxoFileBase): - def __init__(self, fileobj): - f = BinFile(fileobj) - - if f.read_from('4s', f.read_from('I', 4)) != 'MOD0': - raise NxoException('Invalid MOD0 magic') - - f.seek(0) - full = f.read(f.size()) - - filecopy = BinFile(StringIO(full)) - super(MemoryDumpFile, self).__init__(filecopy) class NxoException(Exception): pass -def looks_like_memory_dump(fileobj): - fileobj.seek(0) - header = fileobj.read(8) - if len(header) < 8: - return False - modoff = struct.unpack_from('= len(accept_formats_list): - accept_formats_list = None - accept_formats_index = 0 - return 0 - - ret = accept_formats_list[accept_formats_index] - if not isinstance(ret, dict): - ret = { 'format': ret } - if 'options' not in ret: - ret['options'] = 1 - if 'processor' not in ret: - ret['processor'] = 'arm' - ret['options'] |= 1 | idaapi.ACCEPT_CONTINUE - - accept_formats_index += 1 - - return ret + def accept_file(li, n): + print('accept_file') + if not isinstance(n, int_types) or n == 0: + li.seek(0) + if li.read(4) == b'NSO0': + return 'nxo.py: Switch binary (NSO)' + li.seek(0) + if li.read(4) == b'KIP1': + return 'nxo.py: Switch binary (KIP)' + li.seek(0x10) + if li.read(4) == b'NRO0': + return 'nxo.py: Switch binary (NRO)' + return 0 def ida_make_offset(f, ea): if f.armv7: - idc.MakeDword(ea) + idaapi.create_data(ea, idc.FF_DWORD, 4, idaapi.BADADDR) else: - idc.MakeQword(ea) - idc.OpOff(ea, 0, 0) + idaapi.create_data(ea, idc.FF_QWORD, 8, idaapi.BADADDR) + idc.op_plain_offset(ea, 0, 0) def find_bl_targets(text_start, text_end): targets = set() - for pco in xrange(0, text_end - text_start, 4): - pc = text_start + pco - d = Dword(pc) + for pc in range(text_start, text_end, 4): + d = idc.get_wide_dword(pc) if (d & 0xfc000000) == 0x94000000: imm = d & 0x3ffffff if imm & 0x2000000: @@ -892,73 +601,35 @@ else: targets.add(target) return targets - def load_file(li, neflags, fmt): - idaapi.set_processor_type('arm', SETPROC_ALL|SETPROC_FATAL) - - options = FORMAT_OPTIONS[fmt] - - if OPT_EXEFS_LOAD in options: - ret = load_as_exefs(li, options) - else: - ret = load_one_file(li, options, 0) - - eh_parse = idaapi.find_plugin('eh_parse', True) - if eh_parse: - print 'eh_parse ->', idaapi.run_plugin(eh_parse, 0) - else: - print 'warning: eh_parse missing' - - return ret - - def load_as_exefs(li, options): - dirname = os.path.dirname(idc.get_input_file_path()) - binaries = LOAD_EXEFS_NAMES - binaries = [os.path.join(dirname, i) for i in binaries] - binaries = [i for i in binaries if os.path.exists(i)] - for idx, fname in enumerate(binaries): - with open(fname, 'rb') as f: - if not load_one_file(f, options, idx, os.path.basename(fname)): - return False - return True - - def load_one_file(li, options, idx, basename=None): - bypass_plt = OPT_BYPASS_PLT in options - + def load_file(li, neflags, format): + idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL|idaapi.SETPROC_LOADER) f = load_nxo(li) - - if idx == 0: - if f.armv7: - idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT) - else: - idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_64BIT) - - idc.SetCharPrm(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) - idaapi.set_compiler_id(idaapi.COMP_GNU) - idaapi.add_til2('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1) - # don't create tails - idc.set_inf_attr(idc.INF_AF, idc.get_inf_attr(idc.INF_AF) & ~idc.AF_FTAIL) - - if OPT_LOAD_31_BIT in options: - loadbase = 0x8000000 - step = 0x1000000 - elif f.armv7: - loadbase = 0x60000000 - step = 0x10000000 + if f.armv7: + idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT) else: - loadbase = 0x7100000000 - step = 0x100000000 - loadbase += idx * step + idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT) + + idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) + idaapi.set_compiler_id(idaapi.COMP_GNU) + idaapi.add_til('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1) + + loadbase = 0x60000000 if f.armv7 else 0x7100000000 f.binfile.seek(0) as_string = f.binfile.read(f.bssoff) idaapi.mem2base(as_string, loadbase) + if f.text[1] != None: + li.file2base(f.text[1], loadbase + f.text[2], loadbase + f.text[2] + f.text[3], True) + if f.ro[1] != None: + li.file2base(f.ro[1], loadbase + f.ro[2], loadbase + f.ro[2] + f.ro[3], True) + if f.data[1] != None: + li.file2base(f.data[1], loadbase + f.data[2], loadbase + f.data[2] + f.data[3], True) - seg_prefix = basename if basename is not None else '' for start, end, name, kind in f.sections: if name.startswith('.got'): kind = 'CONST' - idaapi.add_segm(0, loadbase+start, loadbase+end, seg_prefix+name, kind) - segm = idaapi.get_segm_by_name(seg_prefix+name) + idaapi.add_segm(0, loadbase+start, loadbase+end, name, kind) + segm = idaapi.get_segm_by_name(name) if kind == 'CONST': segm.perm = idaapi.SEGPERM_READ elif kind == 'CODE': @@ -979,16 +650,14 @@ else: last_ea = max(loadbase + end for start, end, name, kind in f.sections) undef_entry_size = 8 undef_ea = ((last_ea + 0xFFF) & ~0xFFF) + undef_entry_size # plus 8 so we don't end up on the "end" symbol - - undef_seg = basename + '.UNDEF' if basename is not None else 'UNDEF' - idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, undef_seg, 'XTRN') - segm = idaapi.get_segm_by_name(undef_seg) + idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, "UNDEF", "XTRN") + segm = idaapi.get_segm_by_name("UNDEF") segm.type = idaapi.SEG_XTRN idaapi.update_segm(segm) for i,s in enumerate(f.symbols): if not s.shndx and s.name: - idc.MakeQword(undef_ea) - idaapi.do_name_anyway(undef_ea, s.name) + idaapi.create_data(undef_ea, idc.FF_QWORD, 8, idaapi.BADADDR) + idaapi.force_name(undef_ea, s.name) s.resolved = undef_ea undef_ea += undef_entry_size elif i != 0: @@ -996,9 +665,10 @@ else: s.resolved = loadbase + s.value if s.name: if s.type == STT_FUNC: + print(hex(s.resolved), s.name) idaapi.add_entry(s.resolved, s.resolved, s.name, 0) else: - idaapi.do_name_anyway(s.resolved, s.name) + idaapi.force_name(s.resolved, s.name) else: # NULL symbol @@ -1009,20 +679,17 @@ else: if s.name and s.shndx and s.value: if s.type == STT_FUNC: funcs.add(loadbase+s.value) - symend = loadbase+s.value+s.size - if Dword(symend) != 0: - funcs.add(symend) got_name_lookup = {} for offset, r_type, sym, addend in f.relocations: target = offset + loadbase if r_type in (R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_ABS32): if not sym: - print 'error: relocation at %X failed' % target + print('error: relocation at %X failed' % target) else: - idaapi.put_long(target, sym.resolved) + idaapi.put_dword(target, sym.resolved) elif r_type == R_ARM_RELATIVE: - idaapi.put_long(target, idaapi.get_long(target) + loadbase) + idaapi.put_dword(target, idaapi.get_dword(target) + loadbase) elif r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64): idaapi.put_qword(target, sym.resolved + addend) if addend == 0: @@ -1031,52 +698,20 @@ else: idaapi.put_qword(target, loadbase + addend) if addend < f.textsize: funcs.add(loadbase + addend) - elif r_type == R_FAKE_RELR: - assert not f.armv7 # TODO - addend = idaapi.get_qword(target) - idaapi.put_qword(target, addend + loadbase) - if addend < f.textsize: - funcs.add(loadbase + addend) else: - print 'TODO r_type %d' % (r_type,) + print('TODO r_type %d' % (r_type,)) ida_make_offset(f, target) for func, target in f.plt_entries: if target in got_name_lookup: addr = loadbase + func funcs.add(addr) - idaapi.do_name_anyway(addr, got_name_lookup[target]) + idaapi.force_name(addr, got_name_lookup[target]) - if not f.armv7: - funcs |= find_bl_targets(loadbase, loadbase+f.textsize) - - if bypass_plt: - plt_lookup = f.plt_lookup - for pco in xrange(0, f.textsize, 4): - pc = loadbase + pco - d = Dword(pc) - if (d & 0x7c000000) == (0x94000000 & 0x7c000000): - imm = d & 0x3ffffff - if imm & 0x2000000: - imm |= ~0x1ffffff - if 0 <= imm <= 2: - continue - target = (pc + imm * 4) - loadbase - if target in plt_lookup: - new_target = plt_lookup[target] + loadbase - new_instr = (d & ~0x3ffffff) | (((new_target - pc) / 4) & 0x3ffffff) - idaapi.put_long(pc, new_instr) - - for pco in xrange(0, f.textsize, 4): - pc = loadbase + pco - d = Dword(pc) - if d == 0x14000001: - funcs.add(pc + 4) - - for pc, _ in f.eh_table: - funcs.add(loadbase + pc) + funcs |= find_bl_targets(loadbase, loadbase+f.textsize) for addr in sorted(funcs, reverse=True): - idaapi.auto_make_proc(addr) + idc.AutoMark(addr, idc.AU_CODE) + idc.AutoMark(addr, idc.AU_PROC) return 1