mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-02-09 19:25:10 +01:00
Compare commits
108 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4e99a5e08d | ||
|
9f8d17b9e6 | ||
|
3a5f70dceb | ||
|
e51e11a71c | ||
|
57e15f3622 | ||
|
c6014b533f | ||
|
0c3608d1f4 | ||
|
be19749841 | ||
|
7c31b21d4b | ||
|
9112461620 | ||
|
3522ac18c1 | ||
|
e63cae5c77 | ||
|
c911420d6a | ||
|
570989384b | ||
|
4c81432e94 | ||
|
e1e84d4450 | ||
|
d2656e3948 | ||
|
62abb31122 | ||
|
cb970049db | ||
|
9610f42dc0 | ||
|
02e837d82e | ||
|
7aa0bed869 | ||
|
a80d5b5c86 | ||
|
77d239265d | ||
|
624f8d0d8d | ||
|
9cfd535568 | ||
|
23ba31da1f | ||
|
3b03b9603c | ||
|
912b84c4e3 | ||
|
ff38a32a9b | ||
|
2855b8ee35 | ||
|
00716576cd | ||
|
743634c3fd | ||
|
3394a88a1a | ||
|
a72e39d657 | ||
|
c3fa42d958 | ||
|
126cb8bbdf | ||
|
753cf74bf2 | ||
|
70bf833070 | ||
|
a0ad3ef949 | ||
|
5de551db29 | ||
|
77d17dc4ff | ||
|
4acfac539c | ||
|
c4a5d4db09 | ||
|
10c7a39528 | ||
|
009f581721 | ||
|
027e209073 | ||
|
423a05a1e9 | ||
|
4617fec672 | ||
|
e85bc4db0b | ||
|
39c201e37f | ||
|
ab5cc75684 | ||
|
1e3349e99a | ||
|
76628e273a | ||
|
257ac2bd33 | ||
|
9eb92f37db | ||
|
5b135d12ca | ||
|
c41a6b80d7 | ||
|
05fde7b764 | ||
|
1609f804f2 | ||
|
f35c94810c | ||
|
548b48b2a6 | ||
|
35d93a7c41 | ||
|
410f23035e | ||
|
29cc13543a | ||
|
31ad4eec1d | ||
|
3ccb0ae02b | ||
|
4f7db6e60e | ||
|
a325e18cb5 | ||
|
af41272591 | ||
|
551821e7e2 | ||
|
b081762657 | ||
|
d2c2a94c5e | ||
|
4ff9278d11 | ||
|
21c85c6a4f | ||
|
05090005b7 | ||
|
c0487ad384 | ||
|
ecbe5cd406 | ||
|
4fe139ea52 | ||
|
6922eae3e7 | ||
|
952188fc73 | ||
|
c0a4fc30a8 | ||
|
0b04c89a84 | ||
|
217dd1260a | ||
|
8aa62a54d8 | ||
|
25bae14064 | ||
|
900913fe3b | ||
|
7562f807fd | ||
|
cf5895e04f | ||
|
1f37fbed1d | ||
|
9701d5b2ab | ||
|
c8c76bf8f8 | ||
|
0220f67085 | ||
|
615f8a3ef3 | ||
|
000e382c42 | ||
|
3627356d4b | ||
|
72b0fe6c1c | ||
|
e919b80fa2 | ||
|
fc16f28d0c | ||
|
e09ba765a1 | ||
|
3217df147e | ||
|
1fa41c3e2a | ||
|
db3dc4ebd2 | ||
|
742fd16080 | ||
|
812b2aeb4c | ||
|
46a4357882 | ||
|
872c18c501 | ||
|
afc0e14556 |
@ -3,7 +3,7 @@
|
||||
=====
|
||||
|
||||

|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
|
||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
||||
|
||||
@ -27,7 +27,6 @@ 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
|
||||
|
@ -84,7 +84,7 @@ 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/010000000000b240
|
||||
@ -98,7 +98,7 @@ 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
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Key: debugmode, default: 1.
|
||||
# Desc: Controls whether kernel is debug mode.
|
||||
# Disabling this may break Atmosphere's debugger in a future release.
|
||||
# Disabling this will break Atmosphere.
|
||||
|
||||
# Key: debugmode_user, default: 0.
|
||||
# Desc: Controls whether userland is debug mode.
|
||||
|
@ -1,4 +1,47 @@
|
||||
# Changelog
|
||||
## 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.
|
||||
|
@ -49,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address.
|
||||
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
|
||||
+ R: Register to use as an offset from memory region base.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to write.
|
||||
@ -62,11 +62,13 @@ Code type 0x1 performs a comparison of the contents of memory to a static value.
|
||||
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
|
||||
|
||||
#### Encoding
|
||||
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
|
||||
+ C: Condition to use, see below.
|
||||
+ X: Operand Type, see below.
|
||||
+ r: Offset Register (operand types 1).
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to compare to.
|
||||
|
||||
@ -78,6 +80,9 @@ If the condition is not met, all instructions until the appropriate End or Else
|
||||
+ 5: ==
|
||||
+ 6: !=
|
||||
|
||||
#### Operand Type
|
||||
+ 0: Memory Base + Relative Offset
|
||||
+ 1: Memory Base + Offset Register + Relative Offset
|
||||
---
|
||||
|
||||
### Code Type 0x2: End Conditional Block
|
||||
@ -126,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a
|
||||
`5TMR00AA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
|
||||
+ R: Register to load value into.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
|
||||
@ -137,6 +142,22 @@ Code type 0x5 allows loading a value from memory into a register, either using a
|
||||
+ R: Register to load value into. (This register is also used as the base memory address).
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
#### Load from Register Address Encoding
|
||||
`5T0R2SAA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ R: Register to load value into.
|
||||
+ S: Register to use as the base memory address.
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
#### Load From Fixed Address Encoding with offset register
|
||||
`5TMR3SAA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
|
||||
+ R: Register to load value into.
|
||||
+ S: Register to use as offset register.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
---
|
||||
|
||||
### Code Type 0x6: Store Static Value to Register Memory Address
|
||||
@ -250,7 +271,10 @@ Code type 0x9 allows performing arithmetic on registers.
|
||||
+ 7: Logical Not (discards right-hand operand)
|
||||
+ 8: Logical Xor
|
||||
+ 9: None/Move (discards right-hand operand)
|
||||
|
||||
+ 10: Float Addition, T==4 single T==8 double
|
||||
+ 11: Float Subtraction, T==4 single T==8 double
|
||||
+ 12: Float Multiplication, T==4 single T==8 double
|
||||
+ 13: Float Division, T==4 single T==8 double
|
||||
---
|
||||
|
||||
### Code Type 0xA: Store Register to Memory Address
|
||||
@ -380,6 +404,61 @@ Code type 0xC3 reads or writes a static register with a given register.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xC4: Begin Extended Keypress Conditional Block
|
||||
Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed.
|
||||
|
||||
#### Encoding
|
||||
`C4r00000 kkkkkkkk kkkkkkkk`
|
||||
|
||||
+ r: Auto-repeat, see below.
|
||||
+ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`.
|
||||
|
||||
Note that for multiple button combinations, the bitmasks should be OR'd together.
|
||||
|
||||
#### Auto-repeat
|
||||
|
||||
+ 0: The conditional block executes only once when the keypad mask matches. The mask must stop matching to reset for the next trigger.
|
||||
+ 1: The conditional block executes as long as the keypad mask matches.
|
||||
|
||||
#### Keypad Values
|
||||
Note: This is the direct output of `hidKeysDown()`.
|
||||
|
||||
+ 000000001: A
|
||||
+ 000000002: B
|
||||
+ 000000004: X
|
||||
+ 000000008: Y
|
||||
+ 000000010: Left Stick Pressed
|
||||
+ 000000020: Right Stick Pressed
|
||||
+ 000000040: L
|
||||
+ 000000080: R
|
||||
+ 000000100: ZL
|
||||
+ 000000200: ZR
|
||||
+ 000000400: Plus
|
||||
+ 000000800: Minus
|
||||
+ 000001000: Left
|
||||
+ 000002000: Up
|
||||
+ 000004000: Right
|
||||
+ 000008000: Down
|
||||
+ 000010000: Left Stick Left
|
||||
+ 000020000: Left Stick Up
|
||||
+ 000040000: Left Stick Right
|
||||
+ 000080000: Left Stick Down
|
||||
+ 000100000: Right Stick Left
|
||||
+ 000200000: Right Stick Up
|
||||
+ 000400000: Right Stick Right
|
||||
+ 000800000: Right Stick Down
|
||||
+ 001000000: SL Left Joy-Con
|
||||
+ 002000000: SR Left Joy-Con
|
||||
+ 004000000: SL Right Joy-Con
|
||||
+ 008000000: SR Right Joy-Con
|
||||
+ 010000000: Top button on Poké Ball Plus (Palma) controller
|
||||
+ 020000000: Verification
|
||||
+ 040000000: B button on Left NES/HVC controller in Handheld mode
|
||||
+ 080000000: Left C button in N64 controller
|
||||
+ 100000000: Up C button in N64 controller
|
||||
+ 200000000: Right C button in N64 controller
|
||||
+ 400000000: Down C button in N64 controller
|
||||
|
||||
### Code Type 0xF0: Double Extended-Width Instruction
|
||||
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||
|
||||
|
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emummc
|
||||
branch = develop
|
||||
commit = 9513a5412057b1f1bc44ed8e717c57c726763a88
|
||||
parent = e4d08ae0c5342cdb0875d164522a63ec9d233052
|
||||
commit = d248ea6f700c3e6987549e30a1e2eeb609ce9f8c
|
||||
parent = 9112461620330ba73a74926edd4c08b3cc0310f0
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 17.0.0**
|
||||
**1.0.0 - 19.0.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
24
emummc/source/FS/FS_offsets.c
vendored
24
emummc/source/FS/FS_offsets.c
vendored
@ -69,6 +69,12 @@
|
||||
#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 "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@ -149,6 +155,12 @@ 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);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@ -258,6 +270,18 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
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));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
9
emummc/source/FS/FS_versions.h
vendored
9
emummc/source/FS/FS_versions.h
vendored
@ -101,6 +101,15 @@ enum FS_VER
|
||||
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_MAX,
|
||||
};
|
||||
|
||||
|
59
emummc/source/FS/offsets/1800.h
vendored
Normal file
59
emummc/source/FS/offsets/1800.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
59
emummc/source/FS/offsets/1800_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1800_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
59
emummc/source/FS/offsets/1810.h
vendored
Normal file
59
emummc/source/FS/offsets/1810.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
59
emummc/source/FS/offsets/1810_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1810_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
59
emummc/source/FS/offsets/1900.h
vendored
Normal file
59
emummc/source/FS/offsets/1900.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
59
emummc/source/FS/offsets/1900_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1900_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_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__
|
@ -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 0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7
|
||||
.byte 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70
|
||||
|
||||
/* Mariko Production Master Kek Source. */
|
||||
.byte 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80
|
||||
.byte 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80
|
||||
|
||||
/* 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. */
|
||||
@ -108,6 +108,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.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. */
|
||||
|
||||
/* 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. */
|
||||
@ -127,6 +129,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.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. */
|
||||
|
||||
/* 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. */
|
||||
@ -143,6 +147,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.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. */
|
||||
|
||||
/* 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. */
|
||||
@ -159,6 +165,8 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.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. */
|
||||
|
||||
/* 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. */
|
||||
@ -175,3 +183,5 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
||||
.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. */
|
||||
|
@ -94,7 +94,7 @@ namespace ams::secmon::boot {
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 17);
|
||||
static_assert(pkg1::KeyGeneration_Count == 19);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ namespace ams::nxboot::loader {
|
||||
}
|
||||
|
||||
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
/* Create an execute a decompressor. */
|
||||
/* Create and execute a decompressor. */
|
||||
Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress();
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -23,17 +23,17 @@ namespace ams::nxboot {
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80
|
||||
0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7
|
||||
0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90
|
||||
0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
|
||||
@ -71,6 +71,8 @@ namespace ams::nxboot {
|
||||
{ 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. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
@ -88,6 +90,8 @@ namespace ams::nxboot {
|
||||
{ 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. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
@ -105,6 +109,8 @@ namespace ams::nxboot {
|
||||
{ 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. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
@ -125,6 +131,8 @@ namespace ams::nxboot {
|
||||
{ 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. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
@ -145,6 +153,8 @@ namespace ams::nxboot {
|
||||
{ 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. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};
|
||||
|
@ -80,7 +80,7 @@ namespace ams::nxboot {
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 17);
|
||||
static_assert(pkg1::KeyGeneration_Count == 19);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
@ -259,6 +259,10 @@ namespace ams::nxboot {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -171,6 +171,15 @@ namespace ams::nxboot {
|
||||
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_Count,
|
||||
};
|
||||
|
||||
@ -254,6 +263,15 @@ namespace ams::nxboot {
|
||||
|
||||
{ 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 */
|
||||
};
|
||||
|
||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||
@ -385,15 +403,6 @@ 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;
|
||||
@ -474,78 +483,6 @@ 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<u32>(ips[0]) << 16) | (static_cast<u32>(ips[1]) << 8) | (static_cast<u32>(ips[2]) << 0);
|
||||
if (offset == 0x454F46) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read size. */
|
||||
const u16 cur_size = (static_cast<u32>(ips[3]) << 8) | (static_cast<u32>(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<u32>(ips[5]) << 8) | (static_cast<u32>(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<u32>(ips[0]) << 24) | (static_cast<u32>(ips[1]) << 16) | (static_cast<u32>(ips[2]) << 8) | (static_cast<u32>(ips[3]) << 0);
|
||||
if (offset == 0x45454F46) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read size. */
|
||||
const u16 cur_size = (static_cast<u32>(ips[4]) << 8) | (static_cast<u32>(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<u32>(ips[6]) << 8) | (static_cast<u32>(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
|
||||
};
|
||||
@ -698,6 +635,32 @@ namespace ams::nxboot {
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -891,106 +854,6 @@ 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<u8 *>(ReadFile(std::addressof(file_size), patch_path)); ips != nullptr) {
|
||||
AddIpsPatchToKip(kip_meta, ips, static_cast<s32>(file_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the fs version we're using. */
|
||||
|
@ -60,6 +60,12 @@ 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() {
|
||||
|
@ -97,6 +97,8 @@ 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);
|
||||
}
|
||||
|
@ -229,10 +229,10 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[0x67B] = {
|
||||
0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = {
|
||||
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, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03,
|
||||
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,
|
||||
@ -242,99 +242,98 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = {
|
||||
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, 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, 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,
|
||||
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, 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,
|
||||
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 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = {
|
||||
@ -445,114 +444,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = {
|
||||
0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
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 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = {
|
||||
constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[0x679] = {
|
||||
0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F,
|
||||
0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E,
|
||||
0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03,
|
||||
@ -569,7 +461,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = {
|
||||
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,
|
||||
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,
|
||||
@ -592,7 +484,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = {
|
||||
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,
|
||||
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,
|
||||
@ -602,61 +494,61 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = {
|
||||
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,
|
||||
0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07,
|
||||
0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70,
|
||||
0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02,
|
||||
0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00,
|
||||
0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF,
|
||||
0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6,
|
||||
0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00,
|
||||
0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01,
|
||||
0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00,
|
||||
0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0,
|
||||
0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20,
|
||||
0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50,
|
||||
0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30,
|
||||
0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00,
|
||||
0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C,
|
||||
0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00,
|
||||
0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00,
|
||||
0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D,
|
||||
0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A,
|
||||
0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4,
|
||||
0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06,
|
||||
0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F,
|
||||
0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90,
|
||||
0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C,
|
||||
0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B,
|
||||
0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07,
|
||||
0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E,
|
||||
0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40,
|
||||
0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00,
|
||||
0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06,
|
||||
0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C,
|
||||
0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10,
|
||||
0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06,
|
||||
0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09,
|
||||
0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00,
|
||||
0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12,
|
||||
0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F,
|
||||
0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F,
|
||||
0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F,
|
||||
0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23,
|
||||
0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08,
|
||||
0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC,
|
||||
0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05,
|
||||
0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06,
|
||||
0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7,
|
||||
0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80,
|
||||
0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80,
|
||||
0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00,
|
||||
0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C,
|
||||
0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00,
|
||||
0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC,
|
||||
0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10,
|
||||
0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00,
|
||||
0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = {
|
||||
@ -766,6 +658,113 @@ constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = {
|
||||
0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
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 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,
|
||||
@ -1195,7 +1194,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[0x67B] = {
|
||||
0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = {
|
||||
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,
|
||||
@ -1208,100 +1207,99 @@ constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = {
|
||||
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, 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, 0x48,
|
||||
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, 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,
|
||||
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, 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,
|
||||
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 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = {
|
||||
@ -1412,6 +1410,113 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = {
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[0x67B] = {
|
||||
0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F,
|
||||
0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E,
|
||||
0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03,
|
||||
0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F,
|
||||
0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00,
|
||||
0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
|
||||
0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
|
||||
0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04,
|
||||
0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09,
|
||||
0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17,
|
||||
0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06,
|
||||
0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50,
|
||||
0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88,
|
||||
0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A,
|
||||
0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40,
|
||||
0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00,
|
||||
0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8,
|
||||
0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00,
|
||||
0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00,
|
||||
0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00,
|
||||
0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16,
|
||||
0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00,
|
||||
0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40,
|
||||
0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03,
|
||||
0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00,
|
||||
0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A,
|
||||
0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02,
|
||||
0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03,
|
||||
0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9,
|
||||
0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22,
|
||||
0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00,
|
||||
0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00,
|
||||
0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10,
|
||||
0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12,
|
||||
0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08,
|
||||
0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10,
|
||||
0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12,
|
||||
0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF,
|
||||
0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06,
|
||||
0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E,
|
||||
0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F,
|
||||
0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30,
|
||||
0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F,
|
||||
0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00,
|
||||
0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16,
|
||||
0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01,
|
||||
0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60,
|
||||
0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00,
|
||||
0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09,
|
||||
0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00,
|
||||
0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72,
|
||||
0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B,
|
||||
0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00,
|
||||
0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F,
|
||||
0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00,
|
||||
0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73,
|
||||
0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44,
|
||||
0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07,
|
||||
0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B,
|
||||
0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00,
|
||||
0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C,
|
||||
0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31,
|
||||
0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F,
|
||||
0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B,
|
||||
0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00,
|
||||
0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17,
|
||||
0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41,
|
||||
0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E,
|
||||
0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C,
|
||||
0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00,
|
||||
0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18,
|
||||
0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38,
|
||||
0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D,
|
||||
0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60,
|
||||
0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06,
|
||||
0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A,
|
||||
0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00,
|
||||
0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F,
|
||||
0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0,
|
||||
0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21,
|
||||
0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02,
|
||||
0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61,
|
||||
0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02,
|
||||
0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42,
|
||||
0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C,
|
||||
0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF,
|
||||
0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0,
|
||||
0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF,
|
||||
0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00,
|
||||
0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26,
|
||||
0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF,
|
||||
0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F,
|
||||
0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03,
|
||||
0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00,
|
||||
0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC,
|
||||
0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41,
|
||||
0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80,
|
||||
0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19,
|
||||
0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00,
|
||||
0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17,
|
||||
0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13,
|
||||
0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D,
|
||||
0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00,
|
||||
0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr const u8 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,
|
||||
@ -1520,6 +1625,115 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[0x681] = {
|
||||
0x00,
|
||||
};
|
||||
|
||||
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 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,
|
||||
|
@ -1002,14 +1002,16 @@ 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 << (DstLow - SrcLow)) & Mask); \
|
||||
cur_reg_value |= ((src_value << Shift) & Mask); \
|
||||
} else { \
|
||||
cur_reg_value |= ((src_value >> (SrcLow - DstLow)) & Mask); \
|
||||
cur_reg_value |= ((src_value >> Shift) & Mask); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = 80bf6aeeed03df0871329e1ec32da073a62bf102
|
||||
parent = 9f26419b1a669762d995ebf21ff83b6e1cf56153
|
||||
commit = 989fb7be0c68bf229fe6789428b6c448b6de142a
|
||||
parent = be19749841e581de4cc5d38f39f4de5fa4046c52
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
@ -44,7 +44,7 @@ else ifeq ($(strip $(ATMOSPHERE_COMPILER_NAME)),clang)
|
||||
export ATMOSPHERE_CFLAGS += -Wno-c99-designator -Wno-gnu-alignof-expression -Wno-unused-private-field
|
||||
endif
|
||||
|
||||
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20 -Wno-invalid-offsetof
|
||||
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++23 -Wno-invalid-offsetof
|
||||
export ATMOSPHERE_ASFLAGS :=
|
||||
|
||||
|
||||
|
@ -37,6 +37,8 @@ namespace ams::pkg1 {
|
||||
KeyGeneration_15_0_0 = 0x0E,
|
||||
KeyGeneration_16_0_0 = 0x0F,
|
||||
KeyGeneration_17_0_0 = 0x10,
|
||||
KeyGeneration_18_0_0 = 0x11,
|
||||
KeyGeneration_19_0_0 = 0x12,
|
||||
|
||||
KeyGeneration_Count,
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace ams::pkg2 {
|
||||
constexpr inline int PayloadCount = 3;
|
||||
|
||||
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */
|
||||
constexpr inline int CurrentBootloaderVersion = 0x14;
|
||||
constexpr inline int CurrentBootloaderVersion = 0x16;
|
||||
|
||||
struct Package2Meta {
|
||||
using Magic = util::FourCC<'P','K','2','1'>;
|
||||
|
@ -177,6 +177,7 @@ namespace ams::fuse {
|
||||
}
|
||||
|
||||
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
|
||||
TargetFirmware_19_0_0,
|
||||
TargetFirmware_17_0_0,
|
||||
TargetFirmware_16_0_0,
|
||||
TargetFirmware_15_0_0,
|
||||
|
@ -110,47 +110,47 @@ namespace ams::kern::arch::arm64::init {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
|
||||
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
|
||||
if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= L1BlockSize);
|
||||
virt_addr += L1BlockSize;
|
||||
if (l1_entry->IsBlock() && block_size == L1BlockSize) {
|
||||
if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) {
|
||||
count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Non empty and non-block must be table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L2. */
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
|
||||
if (l2_entry->IsBlock() || l2_entry->IsEmpty()) {
|
||||
const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
|
||||
if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) {
|
||||
const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
|
||||
virt_addr += advance_size;
|
||||
if (l2_entry->IsBlock() && block_size == advance_size) {
|
||||
if (l2_entry->IsMappedBlock() && block_size == advance_size) {
|
||||
count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Non empty and non-block must be table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L3. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
|
||||
/* L3 must be block or empty. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty());
|
||||
|
||||
const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
|
||||
const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
|
||||
virt_addr += advance_size;
|
||||
if (l3_entry->IsBlock() && block_size == advance_size) {
|
||||
if (l3_entry->IsMappedBlock() && block_size == advance_size) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -164,10 +164,10 @@ namespace ams::kern::arch::arm64::init {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
|
||||
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
|
||||
if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= L1BlockSize);
|
||||
if (l1_entry->IsBlock() && block_size == L1BlockSize) {
|
||||
if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) {
|
||||
if ((count++) == index) {
|
||||
return virt_addr;
|
||||
}
|
||||
@ -177,16 +177,16 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* Non empty and non-block must be table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L2. */
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
|
||||
if (l2_entry->IsBlock() || l2_entry->IsEmpty()) {
|
||||
const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
|
||||
if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) {
|
||||
const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
|
||||
if (l2_entry->IsBlock() && block_size == advance_size) {
|
||||
if (l2_entry->IsMappedBlock() && block_size == advance_size) {
|
||||
if ((count++) == index) {
|
||||
return virt_addr;
|
||||
}
|
||||
@ -196,18 +196,18 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* Non empty and non-block must be table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L3. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
|
||||
/* L3 must be block or empty. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty());
|
||||
|
||||
const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
|
||||
const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(static_cast<size_t>(end_virt_addr - virt_addr) >= advance_size);
|
||||
if (l3_entry->IsBlock() && block_size == advance_size) {
|
||||
if (l3_entry->IsMappedBlock() && block_size == advance_size) {
|
||||
if ((count++) == index) {
|
||||
return virt_addr;
|
||||
}
|
||||
@ -220,29 +220,29 @@ namespace ams::kern::arch::arm64::init {
|
||||
PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize);
|
||||
return l1_entry;
|
||||
}
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L2. */
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
const size_t real_size = (l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size);
|
||||
return l2_entry;
|
||||
}
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* Table, so check if we're mapped in L3. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
|
||||
/* L3 must be block. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock());
|
||||
|
||||
const size_t real_size = (l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size);
|
||||
@ -340,7 +340,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* If we don't already have an L2 table, we need to make a new one. */
|
||||
if (!l1_entry->IsTable()) {
|
||||
if (!l1_entry->IsMappedTable()) {
|
||||
KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset);
|
||||
cpu::DataSynchronizationBarrierInnerShareable();
|
||||
*l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
|
||||
@ -371,7 +371,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* If we don't already have an L3 table, we need to make a new one. */
|
||||
if (!l2_entry->IsTable()) {
|
||||
if (!l2_entry->IsMappedTable()) {
|
||||
KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset);
|
||||
cpu::DataSynchronizationBarrierInnerShareable();
|
||||
*l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
|
||||
@ -416,12 +416,12 @@ namespace ams::kern::arch::arm64::init {
|
||||
for (size_t l1_index = 0; l1_index < m_num_entries[0]; l1_index++) {
|
||||
/* Get L1 entry. */
|
||||
L1PageTableEntry * const l1_entry = l1_table + l1_index;
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
/* Unmap the L1 entry, if we should. */
|
||||
if (ShouldUnmap(l1_entry)) {
|
||||
*static_cast<PageTableEntry *>(l1_entry) = InvalidPageTableEntry;
|
||||
}
|
||||
} else if (l1_entry->IsTable()) {
|
||||
} else if (l1_entry->IsMappedTable()) {
|
||||
/* Get the L2 table. */
|
||||
L2PageTableEntry * const l2_table = reinterpret_cast<L2PageTableEntry *>(GetInteger(l1_entry->GetTable()) + phys_to_virt_offset);
|
||||
|
||||
@ -430,7 +430,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
for (size_t l2_index = 0; l2_index < MaxPageTableEntries; ++l2_index) {
|
||||
/* Get L2 entry. */
|
||||
L2PageTableEntry * const l2_entry = l2_table + l2_index;
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
const size_t num_to_clear = (l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize) / L2BlockSize;
|
||||
|
||||
if (ShouldUnmap(l2_entry)) {
|
||||
@ -442,7 +442,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
l2_index = l2_index + num_to_clear - 1;
|
||||
} else if (l2_entry->IsTable()) {
|
||||
} else if (l2_entry->IsMappedTable()) {
|
||||
/* Get the L3 table. */
|
||||
L3PageTableEntry * const l3_table = reinterpret_cast<L3PageTableEntry *>(GetInteger(l2_entry->GetTable()) + phys_to_virt_offset);
|
||||
|
||||
@ -450,7 +450,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
size_t remaining_l3_entries = 0;
|
||||
for (size_t l3_index = 0; l3_index < MaxPageTableEntries; ++l3_index) {
|
||||
/* Get L3 entry. */
|
||||
if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsBlock()) {
|
||||
if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsMappedBlock()) {
|
||||
const size_t num_to_clear = (l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize) / L3BlockSize;
|
||||
|
||||
if (ShouldUnmap(l3_entry)) {
|
||||
@ -498,25 +498,25 @@ namespace ams::kern::arch::arm64::init {
|
||||
/* Get the L1 entry. */
|
||||
const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1));
|
||||
}
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
/* Get the L2 entry. */
|
||||
const L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
return l2_entry->GetBlock() + (GetInteger(virt_addr) & (L2BlockSize - 1));
|
||||
}
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* Get the L3 entry. */
|
||||
const L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock());
|
||||
|
||||
return l3_entry->GetBlock() + (GetInteger(virt_addr) & (L3BlockSize - 1));
|
||||
}
|
||||
@ -561,26 +561,26 @@ namespace ams::kern::arch::arm64::init {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
/* If an L1 block is mapped, update. */
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
UpdateExtents(l1_entry->GetBlock(), L1BlockSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Not a block, so we must have a table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
UpdateExtents(l2_entry->GetBlock(), l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Not a block, so we must have a table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* We must have a mapped l3 entry to inspect. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock());
|
||||
|
||||
UpdateExtents(l3_entry->GetBlock(), l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize);
|
||||
}
|
||||
@ -602,11 +602,11 @@ namespace ams::kern::arch::arm64::init {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
/* If an L1 block is mapped, the address isn't free. */
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!l1_entry->IsTable()) {
|
||||
if (!l1_entry->IsMappedTable()) {
|
||||
/* Not a table, so just move to check the next region. */
|
||||
virt_addr = util::AlignDown(GetInteger(virt_addr) + L1BlockSize, L1BlockSize);
|
||||
continue;
|
||||
@ -615,11 +615,11 @@ namespace ams::kern::arch::arm64::init {
|
||||
/* Table, so check if we're mapped in L2. */
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!l2_entry->IsTable()) {
|
||||
if (!l2_entry->IsMappedTable()) {
|
||||
/* Not a table, so just move to check the next region. */
|
||||
virt_addr = util::AlignDown(GetInteger(virt_addr) + L2BlockSize, L2BlockSize);
|
||||
continue;
|
||||
@ -628,7 +628,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
/* Table, so check if we're mapped in L3. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
|
||||
if (l3_entry->IsBlock()) {
|
||||
if (l3_entry->IsMappedBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -648,7 +648,7 @@ namespace ams::kern::arch::arm64::init {
|
||||
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
|
||||
|
||||
/* Check if an L1 block is present. */
|
||||
if (l1_entry->IsBlock()) {
|
||||
if (l1_entry->IsMappedBlock()) {
|
||||
/* Ensure that we are allowed to have an L1 block here. */
|
||||
const KPhysicalAddress block = l1_entry->GetBlock();
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
|
||||
@ -669,10 +669,10 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* Not a block, so we must be a table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable());
|
||||
|
||||
L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr);
|
||||
if (l2_entry->IsBlock()) {
|
||||
if (l2_entry->IsMappedBlock()) {
|
||||
const KPhysicalAddress block = l2_entry->GetBlock();
|
||||
|
||||
if (l2_entry->IsContiguous()) {
|
||||
@ -720,11 +720,11 @@ namespace ams::kern::arch::arm64::init {
|
||||
}
|
||||
|
||||
/* Not a block, so we must be a table. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable());
|
||||
|
||||
/* We must have a mapped l3 entry to reprotect. */
|
||||
L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock());
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock());
|
||||
const KPhysicalAddress block = l3_entry->GetBlock();
|
||||
|
||||
if (l3_entry->IsContiguous()) {
|
||||
|
@ -93,9 +93,13 @@ namespace ams::kern::arch::arm64 {
|
||||
MESOSPHERE_ASSERT(alignment < L1BlockSize);
|
||||
return KPageTable::GetBlockSize(static_cast<KPageTable::BlockType>(KPageTable::GetBlockType(alignment) + 1));
|
||||
}
|
||||
public:
|
||||
/* TODO: How should this size be determined. Does the KProcess slab count need to go in a header as a define? */
|
||||
static constexpr size_t NumTtbr0Entries = 81;
|
||||
private:
|
||||
static constinit inline const volatile u64 s_ttbr0_entries[NumTtbr0Entries] = {};
|
||||
private:
|
||||
KPageTableManager *m_manager;
|
||||
u64 m_ttbr;
|
||||
u8 m_asid;
|
||||
protected:
|
||||
Result OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll);
|
||||
@ -105,6 +109,9 @@ namespace ams::kern::arch::arm64 {
|
||||
KPageTableManager &GetPageTableManager() const { return *m_manager; }
|
||||
private:
|
||||
constexpr PageTableEntry GetEntryTemplate(const KPageProperties properties) const {
|
||||
/* Check that the property is not kernel execute. */
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_KernelExecute) == 0);
|
||||
|
||||
/* Set basic attributes. */
|
||||
PageTableEntry entry{PageTableEntry::ExtensionFlag_Valid};
|
||||
entry.SetPrivilegedExecuteNever(true);
|
||||
@ -118,22 +125,24 @@ namespace ams::kern::arch::arm64 {
|
||||
/* Set page attribute. */
|
||||
if (properties.io) {
|
||||
MESOSPHERE_ABORT_UNLESS(!properties.uncached);
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0);
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0);
|
||||
|
||||
entry.SetPageAttribute(PageTableEntry::PageAttribute_Device_nGnRnE)
|
||||
.SetUserExecuteNever(true);
|
||||
} else if (properties.uncached) {
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0);
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0);
|
||||
|
||||
entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable);
|
||||
entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable)
|
||||
.SetUserExecuteNever(true);
|
||||
} else {
|
||||
entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemory);
|
||||
}
|
||||
|
||||
/* Set user execute never bit. */
|
||||
if (properties.perm != KMemoryPermission_UserReadExecute) {
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0);
|
||||
entry.SetUserExecuteNever(true);
|
||||
if ((properties.perm & KMemoryPermission_UserExecute) != 0) {
|
||||
/* Check that the permission is either r--/--x or r--/r-x. */
|
||||
MESOSPHERE_ABORT_UNLESS((properties.perm & ~ams::svc::MemoryPermission_Read) == (KMemoryPermission_KernelRead | KMemoryPermission_UserExecute));
|
||||
} else {
|
||||
entry.SetUserExecuteNever(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set AP[1] based on perm. */
|
||||
@ -168,53 +177,42 @@ namespace ams::kern::arch::arm64 {
|
||||
return entry;
|
||||
}
|
||||
public:
|
||||
constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ }
|
||||
constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_asid() { /* ... */ }
|
||||
explicit KPageTable() { /* ... */ }
|
||||
|
||||
static NOINLINE void Initialize(s32 core_id);
|
||||
|
||||
ALWAYS_INLINE void Activate(u32 proc_id) {
|
||||
cpu::SwitchProcess(m_ttbr, proc_id);
|
||||
static const volatile u64 &GetTtbr0Entry(size_t index) { return s_ttbr0_entries[index]; }
|
||||
|
||||
static ALWAYS_INLINE u64 GetKernelTtbr0() {
|
||||
return s_ttbr0_entries[0];
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void ActivateKernel() {
|
||||
/* Activate, using asid 0 and process id = 0xFFFFFFFF */
|
||||
cpu::SwitchProcess(GetKernelTtbr0(), 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void ActivateProcess(size_t proc_idx, u32 proc_id) {
|
||||
cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id);
|
||||
}
|
||||
|
||||
NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
|
||||
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag 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);
|
||||
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index);
|
||||
Result Finalize();
|
||||
private:
|
||||
Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
|
||||
|
||||
Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll);
|
||||
|
||||
Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) {
|
||||
switch (page_size) {
|
||||
case L1BlockSize:
|
||||
R_RETURN(this->MapL1Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll));
|
||||
case L2ContiguousBlockSize:
|
||||
entry_template.SetContiguous(true);
|
||||
[[fallthrough]];
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
case L2TegraSmmuBlockSize:
|
||||
#endif
|
||||
case L2BlockSize:
|
||||
R_RETURN(this->MapL2Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll));
|
||||
case L3ContiguousBlockSize:
|
||||
entry_template.SetContiguous(true);
|
||||
[[fallthrough]];
|
||||
case L3BlockSize:
|
||||
R_RETURN(this->MapL3Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll));
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll);
|
||||
|
||||
Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll);
|
||||
|
||||
bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list);
|
||||
bool MergePages(TraversalContext *context, PageLinkedList *page_list);
|
||||
void MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list);
|
||||
|
||||
ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
|
||||
Result SeparatePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool reuse_ll);
|
||||
|
||||
Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll);
|
||||
|
||||
@ -224,7 +222,6 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
static ALWAYS_INLINE void ClearPageTable(KVirtualAddress table) {
|
||||
cpu::ClearPageToZero(GetVoidPointer(table));
|
||||
cpu::DataSynchronizationBarrierInnerShareable();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void OnTableUpdated() const {
|
||||
|
@ -20,18 +20,22 @@
|
||||
|
||||
namespace ams::kern::arch::arm64 {
|
||||
|
||||
constexpr size_t BlocksPerContiguousBlock = 0x10;
|
||||
constexpr size_t BlocksPerTable = PageSize / sizeof(u64);
|
||||
|
||||
constexpr size_t L1BlockSize = 1_GB;
|
||||
constexpr size_t L1ContiguousBlockSize = 0x10 * L1BlockSize;
|
||||
constexpr size_t L1ContiguousBlockSize = BlocksPerContiguousBlock * L1BlockSize;
|
||||
constexpr size_t L2BlockSize = 2_MB;
|
||||
constexpr size_t L2ContiguousBlockSize = 0x10 * L2BlockSize;
|
||||
constexpr size_t L2ContiguousBlockSize = BlocksPerContiguousBlock * L2BlockSize;
|
||||
constexpr size_t L3BlockSize = PageSize;
|
||||
constexpr size_t L3ContiguousBlockSize = 0x10 * L3BlockSize;
|
||||
constexpr size_t L3ContiguousBlockSize = BlocksPerContiguousBlock * L3BlockSize;
|
||||
|
||||
class PageTableEntry {
|
||||
public:
|
||||
struct InvalidTag{};
|
||||
struct TableTag{};
|
||||
struct BlockTag{};
|
||||
struct SeparateContiguousTag{};
|
||||
|
||||
enum Permission : u64 {
|
||||
Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)),
|
||||
@ -122,6 +126,25 @@ namespace ams::kern::arch::arm64 {
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* 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<u64>(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<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(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))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
protected:
|
||||
constexpr ALWAYS_INLINE u64 GetBits(size_t offset, size_t count) const {
|
||||
return (m_attributes >> offset) & ((1ul << count) - 1);
|
||||
@ -165,14 +188,23 @@ namespace ams::kern::arch::arm64 {
|
||||
constexpr ALWAYS_INLINE Shareable GetShareable() const { return static_cast<Shareable>(this->SelectBits(8, 2)); }
|
||||
constexpr ALWAYS_INLINE PageAttribute GetPageAttribute() const { return static_cast<PageAttribute>(this->SelectBits(2, 3)); }
|
||||
constexpr ALWAYS_INLINE int GetAccessFlagInteger() const { return static_cast<int>(this->GetBits(10, 1)); }
|
||||
constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast<int>(this->GetBits(8, 2)); }
|
||||
constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast<int>(this->GetBits(8, 2)); }
|
||||
constexpr ALWAYS_INLINE int GetPageAttributeInteger() const { return static_cast<int>(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 IsMapped() const { return this->GetBits(0, 1) != 0; }
|
||||
|
||||
constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; }
|
||||
@ -186,8 +218,16 @@ namespace ams::kern::arch::arm64 {
|
||||
constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; }
|
||||
constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast<u64>(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; }
|
||||
|
||||
constexpr ALWAYS_INLINE size_t GetTableReferenceCount() const { return this->GetBits(2, 10); }
|
||||
constexpr ALWAYS_INLINE decltype(auto) SetTableReferenceCount(size_t num) { this->SetBits(2, 10, num); return *this; }
|
||||
|
||||
constexpr ALWAYS_INLINE decltype(auto) OpenTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() + num <= BlocksPerTable + 1); return this->SetTableReferenceCount(this->GetTableReferenceCount() + num); }
|
||||
constexpr ALWAYS_INLINE decltype(auto) CloseTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() >= num); return this->SetTableReferenceCount(this->GetTableReferenceCount() - num); }
|
||||
|
||||
constexpr ALWAYS_INLINE decltype(auto) SetValid() { MESOSPHERE_ASSERT((m_attributes & ExtensionFlag_Valid) == 0); m_attributes |= ExtensionFlag_Valid; return *this; }
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const {
|
||||
constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
|
||||
constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
|
||||
return m_attributes & BaseMask;
|
||||
}
|
||||
|
||||
@ -196,10 +236,45 @@ namespace ams::kern::arch::arm64 {
|
||||
return (m_attributes & BaseMaskForMerge) == attr;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const {
|
||||
static constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateContiguousMask(size_t idx) {
|
||||
constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast<u64>((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<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
|
||||
if (idx == 0) {
|
||||
return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody;
|
||||
} else if (idx < BlocksPerContiguousBlock) {
|
||||
return BaseMask | ExtensionFlag_DisableMergeHeadAndBody;
|
||||
} else if (idx < BlocksPerTable - 1) {
|
||||
return BaseMask;
|
||||
} else {
|
||||
return BaseMask | ExtensionFlag_DisableMergeTail;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparate(size_t idx) const {
|
||||
return m_attributes & GetEntryTemplateForSeparateMask(idx);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafe() const {
|
||||
return m_attributes;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const {
|
||||
return m_attributes;
|
||||
}
|
||||
protected:
|
||||
constexpr ALWAYS_INLINE u64 GetRawAttributes() const {
|
||||
return m_attributes;
|
||||
@ -229,7 +304,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<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid)
|
||||
: PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x1)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -291,7 +366,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<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid)
|
||||
: PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x1)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -356,12 +431,13 @@ namespace ams::kern::arch::arm64 {
|
||||
constexpr explicit ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ }
|
||||
|
||||
constexpr explicit ALWAYS_INLINE L3PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig)
|
||||
: PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | static_cast<u64>(ExtensionFlag_TestTableMask))
|
||||
: PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | 0x3)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsBlock() const { return (GetRawAttributes() & ExtensionFlag_TestTableMask) == ExtensionFlag_TestTableMask; }
|
||||
constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 3; }
|
||||
|
||||
constexpr ALWAYS_INLINE KPhysicalAddress GetBlock() const {
|
||||
return this->SelectBits(12, 36);
|
||||
|
@ -30,16 +30,24 @@ 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 {
|
||||
const L1PageTableEntry *l1_entry;
|
||||
const L2PageTableEntry *l2_entry;
|
||||
const L3PageTableEntry *l3_entry;
|
||||
PageTableEntry *level_entries[EntryLevel_Count];
|
||||
EntryLevel level;
|
||||
bool is_contiguous;
|
||||
};
|
||||
private:
|
||||
static constexpr size_t PageBits = util::CountTrailingZeros(PageSize);
|
||||
@ -52,11 +60,19 @@ namespace ams::kern::arch::arm64 {
|
||||
return (value >> Offset) & ((1ul << Count) - 1);
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE u64 GetBits(u64 value, size_t offset, size_t count) {
|
||||
return (value >> offset) & ((1ul << count) - 1);
|
||||
}
|
||||
|
||||
template<size_t Offset, size_t Count>
|
||||
constexpr ALWAYS_INLINE u64 SelectBits(u64 value) {
|
||||
static constexpr ALWAYS_INLINE u64 SelectBits(u64 value) {
|
||||
return value & (((1ul << Count) - 1) << Offset);
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE u64 SelectBits(u64 value, size_t offset, size_t count) {
|
||||
return value & (((1ul << count) - 1) << offset);
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL0Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 0), LevelBits>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL1Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 1), LevelBits>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL2Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 2), LevelBits>(GetInteger(addr)); }
|
||||
@ -69,13 +85,14 @@ namespace ams::kern::arch::arm64 {
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetContiguousL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2) + 4>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetContiguousL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3) + 4>(GetInteger(addr)); }
|
||||
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetBlock(const PageTableEntry *pte, EntryLevel level) { return SelectBits(pte->GetRawAttributesUnsafe(), PageBits + LevelBits * level, LevelBits * (NumLevels + 1 - level)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetOffset(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), 0, PageBits + LevelBits * level); }
|
||||
|
||||
static ALWAYS_INLINE KVirtualAddress GetPageTableVirtualAddress(KPhysicalAddress addr) {
|
||||
return KMemoryLayout::GetLinearVirtualAddress(addr);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const;
|
||||
ALWAYS_INLINE bool ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const;
|
||||
ALWAYS_INLINE bool ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const;
|
||||
public:
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); }
|
||||
private:
|
||||
L1PageTableEntry *m_table;
|
||||
bool m_is_kernel;
|
||||
@ -104,11 +121,17 @@ namespace ams::kern::arch::arm64 {
|
||||
ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KProcessAddress address) const {
|
||||
return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address);
|
||||
}
|
||||
|
||||
static constexpr size_t GetBlockSize(EntryLevel level, bool contiguous = false) {
|
||||
return 1 << (PageBits + LevelBits * level + 4 * contiguous);
|
||||
}
|
||||
public:
|
||||
constexpr explicit KPageTableImpl(util::ConstantInitializeTag) : m_table(), m_is_kernel(), m_num_entries() { /* ... */ }
|
||||
|
||||
explicit KPageTableImpl() { /* ... */ }
|
||||
|
||||
size_t GetNumL1Entries() const { return m_num_entries; }
|
||||
|
||||
NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end);
|
||||
NOINLINE void InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end);
|
||||
L1PageTableEntry *Finalize();
|
||||
@ -120,6 +143,17 @@ namespace ams::kern::arch::arm64 {
|
||||
bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;
|
||||
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const;
|
||||
|
||||
static bool MergePages(KVirtualAddress *out, TraversalContext *context);
|
||||
void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const;
|
||||
|
||||
KProcessAddress GetAddressForContext(const TraversalContext *context) const {
|
||||
KProcessAddress addr = m_is_kernel ? static_cast<uintptr_t>(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0;
|
||||
for (u32 level = context->level; level <= EntryLevel_L1; ++level) {
|
||||
addr += ((reinterpret_cast<uintptr_t>(context->level_entries[level]) / sizeof(PageTableEntry)) & (BlocksPerTable - 1)) << (PageBits + LevelBits * level);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ namespace ams::kern::arch::arm64 {
|
||||
private:
|
||||
KPageTable m_page_table;
|
||||
public:
|
||||
void Activate(u64 id) {
|
||||
void Activate(size_t process_index, u64 id) {
|
||||
/* Activate the page table with the specified contextidr. */
|
||||
m_page_table.Activate(id);
|
||||
m_page_table.ActivateProcess(process_index, id);
|
||||
}
|
||||
|
||||
Result Initialize(ams::svc::CreateProcessFlag 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(as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, system_resource, resource_limit));
|
||||
Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) {
|
||||
R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index));
|
||||
}
|
||||
|
||||
void Finalize() { m_page_table.Finalize(); }
|
||||
@ -110,12 +110,12 @@ namespace ams::kern::arch::arm64 {
|
||||
R_RETURN(m_page_table.MapRegion(region_type, perm));
|
||||
}
|
||||
|
||||
Result MapInsecureMemory(KProcessAddress address, size_t size) {
|
||||
R_RETURN(m_page_table.MapInsecureMemory(address, size));
|
||||
Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size) {
|
||||
R_RETURN(m_page_table.MapInsecurePhysicalMemory(address, size));
|
||||
}
|
||||
|
||||
Result UnmapInsecureMemory(KProcessAddress address, size_t size) {
|
||||
R_RETURN(m_page_table.UnmapInsecureMemory(address, size));
|
||||
Result UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size) {
|
||||
R_RETURN(m_page_table.UnmapInsecurePhysicalMemory(address, size));
|
||||
}
|
||||
|
||||
Result MapPageGroup(KProcessAddress addr, const KPageGroup &pg, KMemoryState state, KMemoryPermission perm) {
|
||||
@ -154,8 +154,8 @@ namespace ams::kern::arch::arm64 {
|
||||
R_RETURN(m_page_table.InvalidateCurrentProcessDataCache(address, size));
|
||||
}
|
||||
|
||||
Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) {
|
||||
R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size));
|
||||
Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod) {
|
||||
R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size, force_debug_prod));
|
||||
}
|
||||
|
||||
Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) {
|
||||
@ -316,6 +316,8 @@ 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(); }
|
||||
|
@ -29,8 +29,7 @@ namespace ams::kern::arch::arm64 {
|
||||
NOINLINE void Initialize(s32 core_id);
|
||||
|
||||
void Activate() {
|
||||
/* Activate, using process id = 0xFFFFFFFF */
|
||||
m_page_table.Activate(0xFFFFFFFF);
|
||||
m_page_table.ActivateKernel();
|
||||
}
|
||||
|
||||
void ActivateForInit() {
|
||||
|
@ -16,11 +16,10 @@
|
||||
#pragma once
|
||||
#include <mesosphere/kern_common.hpp>
|
||||
#include <mesosphere/kern_select_cpu.hpp>
|
||||
#include <mesosphere/kern_select_interrupt_manager.hpp>
|
||||
|
||||
namespace ams::kern::arch::arm64::smc {
|
||||
|
||||
template<int SmcId, bool DisableInterrupt>
|
||||
template<int SmcId>
|
||||
void SecureMonitorCall(u64 *buf) {
|
||||
/* Load arguments into registers. */
|
||||
register u64 x0 asm("x0") = buf[0];
|
||||
@ -32,34 +31,18 @@ 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. */
|
||||
if constexpr (DisableInterrupt) {
|
||||
KScopedInterruptDisable di;
|
||||
__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"
|
||||
);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
/* Restore the current thread pointer into X18. */
|
||||
cpu::SetCurrentThreadPointerValue(current_thread_pointer_value);
|
||||
|
||||
/* Store arguments to output. */
|
||||
buf[0] = x0;
|
||||
@ -78,18 +61,18 @@ namespace ams::kern::arch::arm64::smc {
|
||||
PsciFunction_CpuOn = 0xC4000003,
|
||||
};
|
||||
|
||||
template<int SmcId, bool DisableInterrupt>
|
||||
template<int SmcId>
|
||||
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<SmcId, DisableInterrupt>(args.r);
|
||||
SecureMonitorCall<SmcId>(args.r);
|
||||
|
||||
return args.r[0];
|
||||
}
|
||||
|
||||
template<int SmcId, bool DisableInterrupt>
|
||||
template<int SmcId>
|
||||
u64 CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
||||
return PsciCall<SmcId, DisableInterrupt>(PsciFunction_CpuOn, core_id, entrypoint, arg);
|
||||
return PsciCall<SmcId>(PsciFunction_CpuOn, core_id, entrypoint, arg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,10 +21,22 @@ namespace ams::kern::arch::arm64 {
|
||||
void UserspaceAccessFunctionAreaBegin();
|
||||
|
||||
class UserspaceAccess {
|
||||
private:
|
||||
static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src);
|
||||
public:
|
||||
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<uintptr_t>(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src);
|
||||
}
|
||||
|
||||
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 s32 CopyStringFromUser(void *dst, const void *src, size_t size);
|
||||
|
||||
|
@ -24,4 +24,8 @@ namespace ams::kern {
|
||||
constexpr inline size_t MainMemorySize = 4_GB;
|
||||
constexpr inline size_t MainMemorySizeMax = 8_GB;
|
||||
|
||||
constexpr inline u32 MinimumMemoryManagerAlignmentShifts[] = {
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
};
|
||||
public:
|
||||
/* Initialization. */
|
||||
static NOINLINE void ConfigureKTargetSystem();
|
||||
static NOINLINE void InitializePhase1();
|
||||
static NOINLINE void InitializePhase2();
|
||||
static NOINLINE u32 GetCreateProcessMemoryPool();
|
||||
|
@ -32,6 +32,7 @@ namespace ams::kern {
|
||||
struct InitialProcessBinaryLayout {
|
||||
uintptr_t address;
|
||||
uintptr_t _08;
|
||||
uintptr_t kern_address;
|
||||
};
|
||||
|
||||
struct InitialProcessBinaryLayoutWithSize {
|
||||
|
@ -39,14 +39,16 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
|
||||
Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s32 value, s64 timeout) {
|
||||
Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s64 value, s64 timeout) {
|
||||
switch (type) {
|
||||
case ams::svc::ArbitrationType_WaitIfLessThan:
|
||||
R_RETURN(this->WaitIfLessThan(addr, value, false, timeout));
|
||||
R_RETURN(this->WaitIfLessThan(addr, static_cast<s32>(value), false, timeout));
|
||||
case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan:
|
||||
R_RETURN(this->WaitIfLessThan(addr, value, true, timeout));
|
||||
R_RETURN(this->WaitIfLessThan(addr, static_cast<s32>(value), true, timeout));
|
||||
case ams::svc::ArbitrationType_WaitIfEqual:
|
||||
R_RETURN(this->WaitIfEqual(addr, value, timeout));
|
||||
R_RETURN(this->WaitIfEqual(addr, static_cast<s32>(value), timeout));
|
||||
case ams::svc::ArbitrationType_WaitIfEqual64:
|
||||
R_RETURN(this->WaitIfEqual64(addr, value, timeout));
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
@ -56,6 +58,7 @@ namespace ams::kern {
|
||||
Result SignalAndModifyByWaitingCountIfEqual(uintptr_t addr, s32 value, s32 count);
|
||||
Result WaitIfLessThan(uintptr_t addr, s32 value, bool decrement, s64 timeout);
|
||||
Result WaitIfEqual(uintptr_t addr, s32 value, s64 timeout);
|
||||
Result WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ namespace ams::kern {
|
||||
size_t m_size;
|
||||
Type m_type;
|
||||
public:
|
||||
static uintptr_t GetAddressSpaceStart(size_t width, Type type);
|
||||
static size_t GetAddressSpaceSize(size_t width, Type type);
|
||||
static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type);
|
||||
static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type);
|
||||
|
||||
static void SetAddressSpaceSize(size_t width, Type type, size_t size);
|
||||
|
||||
|
@ -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 crash if accessed. */
|
||||
/* Set our object to a debug sentinel value, which will cause a crash if accessed. */
|
||||
m_object = reinterpret_cast<T *>(1);
|
||||
|
||||
/* Close reference to our object. */
|
||||
|
@ -168,9 +168,10 @@ namespace ams::kern {
|
||||
struct DebugFlags {
|
||||
using IdBits = Field<0, CapabilityId<CapabilityType::DebugFlags> + 1>;
|
||||
|
||||
DEFINE_FIELD(AllowDebug, IdBits, 1, bool);
|
||||
DEFINE_FIELD(ForceDebug, AllowDebug, 1, bool);
|
||||
DEFINE_FIELD(Reserved, ForceDebug, 13);
|
||||
DEFINE_FIELD(AllowDebug, IdBits, 1, bool);
|
||||
DEFINE_FIELD(ForceDebugProd, AllowDebug, 1, bool);
|
||||
DEFINE_FIELD(ForceDebug, ForceDebugProd, 1, bool);
|
||||
DEFINE_FIELD(Reserved, ForceDebug, 12);
|
||||
};
|
||||
|
||||
#undef DEFINE_FIELD
|
||||
@ -192,7 +193,7 @@ namespace ams::kern {
|
||||
u32 m_program_type;
|
||||
private:
|
||||
constexpr bool SetSvcAllowed(u32 id) {
|
||||
if (AMS_LIKELY(id < m_svc_access_flags.GetCount())) {
|
||||
if (AMS_LIKELY(id < static_cast<u32>(m_svc_access_flags.GetCount()))) {
|
||||
m_svc_access_flags[id] = true;
|
||||
return true;
|
||||
} else {
|
||||
@ -201,7 +202,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
constexpr bool SetInterruptPermitted(u32 id) {
|
||||
if (AMS_LIKELY(id < m_irq_access_flags.GetCount())) {
|
||||
if (AMS_LIKELY(id < static_cast<u32>(m_irq_access_flags.GetCount()))) {
|
||||
m_irq_access_flags[id] = true;
|
||||
return true;
|
||||
} else {
|
||||
@ -255,6 +256,10 @@ namespace ams::kern {
|
||||
return m_debug_capabilities.Get<DebugFlags::AllowDebug>();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebugProd() const {
|
||||
return m_debug_capabilities.Get<DebugFlags::ForceDebugProd>();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebug() const {
|
||||
return m_debug_capabilities.Get<DebugFlags::ForceDebug>();
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ namespace ams::kern {
|
||||
KLightLock m_lock;
|
||||
KProcess::State m_old_process_state;
|
||||
bool m_is_attached;
|
||||
bool m_is_force_debug_prod;
|
||||
public:
|
||||
explicit KDebugBase() { /* ... */ }
|
||||
protected:
|
||||
@ -62,6 +63,10 @@ namespace ams::kern {
|
||||
return m_is_attached;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool IsForceDebugProd() const {
|
||||
return m_is_force_debug_prod;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool OpenProcess() {
|
||||
return m_process_holder.Open();
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ namespace ams::kern {
|
||||
};
|
||||
|
||||
constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) {
|
||||
return static_cast<KMemoryPermission>((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None));
|
||||
return static_cast<KMemoryPermission>((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));
|
||||
}
|
||||
|
||||
enum KMemoryAttribute : u8 {
|
||||
@ -200,7 +200,8 @@ namespace ams::kern {
|
||||
KMemoryBlockDisableMergeAttribute_DeviceLeft = (1u << 1),
|
||||
KMemoryBlockDisableMergeAttribute_IpcLeft = (1u << 2),
|
||||
KMemoryBlockDisableMergeAttribute_Locked = (1u << 3),
|
||||
KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 4),
|
||||
/* ... */
|
||||
KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 5),
|
||||
|
||||
KMemoryBlockDisableMergeAttribute_AllLeft = KMemoryBlockDisableMergeAttribute_Normal | KMemoryBlockDisableMergeAttribute_DeviceLeft | KMemoryBlockDisableMergeAttribute_IpcLeft | KMemoryBlockDisableMergeAttribute_Locked,
|
||||
KMemoryBlockDisableMergeAttribute_AllRight = KMemoryBlockDisableMergeAttribute_DeviceRight,
|
||||
@ -288,18 +289,18 @@ namespace ams::kern {
|
||||
|
||||
class KMemoryBlock : public util::IntrusiveRedBlackTreeBaseNode<KMemoryBlock> {
|
||||
private:
|
||||
u16 m_device_disable_merge_left_count;
|
||||
u16 m_device_disable_merge_right_count;
|
||||
KProcessAddress m_address;
|
||||
size_t m_num_pages;
|
||||
KMemoryState m_memory_state;
|
||||
u16 m_ipc_lock_count;
|
||||
u16 m_device_use_count;
|
||||
u16 m_ipc_disable_merge_count;
|
||||
KMemoryPermission m_permission;
|
||||
KMemoryPermission m_original_permission;
|
||||
KMemoryAttribute m_attribute;
|
||||
KMemoryBlockDisableMergeAttribute m_disable_merge_attribute;
|
||||
KProcessAddress m_address;
|
||||
u32 m_num_pages;
|
||||
KMemoryState m_memory_state;
|
||||
u16 m_ipc_lock_count;
|
||||
u16 m_ipc_disable_merge_count;
|
||||
u16 m_device_use_count;
|
||||
u16 m_device_disable_merge_left_count;
|
||||
u16 m_device_disable_merge_right_count;
|
||||
public:
|
||||
static constexpr ALWAYS_INLINE int Compare(const KMemoryBlock &lhs, const KMemoryBlock &rhs) {
|
||||
if (lhs.GetAddress() < rhs.GetAddress()) {
|
||||
@ -343,6 +344,10 @@ namespace ams::kern {
|
||||
return m_ipc_disable_merge_count;
|
||||
}
|
||||
|
||||
constexpr u16 GetDeviceUseCount() const {
|
||||
return m_device_use_count;
|
||||
}
|
||||
|
||||
constexpr KMemoryPermission GetPermission() const {
|
||||
return m_permission;
|
||||
}
|
||||
@ -374,16 +379,15 @@ namespace ams::kern {
|
||||
public:
|
||||
explicit KMemoryBlock() { /* ... */ }
|
||||
|
||||
constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr)
|
||||
: util::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(util::ConstantInitialize), m_device_disable_merge_left_count(),
|
||||
m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0),
|
||||
m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None),
|
||||
m_attribute(attr), m_disable_merge_attribute()
|
||||
constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr)
|
||||
: util::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(util::ConstantInitialize), m_permission(p), m_original_permission(KMemoryPermission_None),
|
||||
m_attribute(attr), m_disable_merge_attribute(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0),
|
||||
m_ipc_disable_merge_count(), m_device_use_count(0), m_device_disable_merge_left_count(), m_device_disable_merge_right_count()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) {
|
||||
constexpr void Initialize(KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
m_device_disable_merge_left_count = 0;
|
||||
m_device_disable_merge_right_count = 0;
|
||||
|
@ -164,6 +164,7 @@ namespace ams::kern {
|
||||
size_t m_num_managers;
|
||||
u64 m_optimized_process_ids[Pool_Count];
|
||||
bool m_has_optimized_process[Pool_Count];
|
||||
s32 m_min_heap_indexes[Pool_Count];
|
||||
private:
|
||||
Impl &GetManager(KPhysicalAddress address) {
|
||||
return m_managers[KMemoryLayout::GetPhysicalLinearRegion(address).GetAttributes()];
|
||||
@ -185,21 +186,21 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
|
||||
Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random);
|
||||
Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index);
|
||||
public:
|
||||
KMemoryManager()
|
||||
: m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process()
|
||||
: m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process(), m_min_heap_indexes()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size);
|
||||
NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts);
|
||||
|
||||
NOINLINE Result InitializeOptimizedMemory(u64 process_id, Pool pool);
|
||||
NOINLINE void FinalizeOptimizedMemory(u64 process_id, Pool pool);
|
||||
|
||||
NOINLINE KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
|
||||
NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option);
|
||||
NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_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 {
|
||||
@ -299,6 +300,10 @@ namespace ams::kern {
|
||||
manager->DumpFreeList();
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetMinimumAlignment(Pool pool) {
|
||||
return KPageHeap::GetBlockSize(m_min_heap_indexes[pool]);
|
||||
}
|
||||
public:
|
||||
static size_t CalculateManagementOverheadSize(size_t region_size) {
|
||||
return Impl::CalculateManagementOverheadSize(region_size);
|
||||
|
@ -145,6 +145,8 @@ 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);
|
||||
}
|
||||
|
@ -62,18 +62,21 @@ namespace ams::kern {
|
||||
KPhysicalAddress m_address;
|
||||
size_t m_size;
|
||||
bool m_heap;
|
||||
u8 m_attr;
|
||||
public:
|
||||
constexpr MemoryRange() : m_address(Null<KPhysicalAddress>), m_size(0), m_heap(false) { /* ... */ }
|
||||
constexpr MemoryRange() : m_address(Null<KPhysicalAddress>), m_size(0), m_heap(false), m_attr(0) { /* ... */ }
|
||||
|
||||
void Set(KPhysicalAddress address, size_t size, bool heap) {
|
||||
void Set(KPhysicalAddress address, size_t size, bool heap, u8 attr) {
|
||||
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();
|
||||
@ -86,6 +89,15 @@ 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,
|
||||
@ -165,15 +177,9 @@ namespace ams::kern {
|
||||
private:
|
||||
KProcessAddress m_address_space_start;
|
||||
KProcessAddress m_address_space_end;
|
||||
KProcessAddress m_heap_region_start;
|
||||
KProcessAddress m_heap_region_end;
|
||||
KProcessAddress m_region_starts[RegionType_Count];
|
||||
KProcessAddress m_region_ends[RegionType_Count];
|
||||
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;
|
||||
@ -183,6 +189,7 @@ 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;
|
||||
@ -203,12 +210,12 @@ namespace ams::kern {
|
||||
MemoryFillValue m_stack_fill_value;
|
||||
public:
|
||||
constexpr explicit KPageTableBase(util::ConstantInitializeTag)
|
||||
: m_address_space_start(Null<KProcessAddress>), m_address_space_end(Null<KProcessAddress>), m_heap_region_start(Null<KProcessAddress>),
|
||||
m_heap_region_end(Null<KProcessAddress>), m_current_heap_end(Null<KProcessAddress>), m_alias_region_start(Null<KProcessAddress>),
|
||||
m_alias_region_end(Null<KProcessAddress>), m_stack_region_start(Null<KProcessAddress>), m_stack_region_end(Null<KProcessAddress>),
|
||||
m_kernel_map_region_start(Null<KProcessAddress>), m_kernel_map_region_end(Null<KProcessAddress>), m_alias_code_region_start(Null<KProcessAddress>),
|
||||
: m_address_space_start(Null<KProcessAddress>), m_address_space_end(Null<KProcessAddress>),
|
||||
m_region_starts{Null<KProcessAddress>, Null<KProcessAddress>, Null<KProcessAddress>, Null<KProcessAddress>},
|
||||
m_region_ends{Null<KProcessAddress>, Null<KProcessAddress>, Null<KProcessAddress>, Null<KProcessAddress>},
|
||||
m_current_heap_end(Null<KProcessAddress>), m_alias_code_region_start(Null<KProcessAddress>),
|
||||
m_alias_code_region_end(Null<KProcessAddress>), m_code_region_start(Null<KProcessAddress>), m_code_region_end(Null<KProcessAddress>),
|
||||
m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(),
|
||||
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_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(),
|
||||
@ -220,7 +227,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 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);
|
||||
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);
|
||||
|
||||
void Finalize();
|
||||
|
||||
@ -236,7 +243,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
|
||||
return this->Contains(addr, size) && m_alias_region_start <= addr && addr + size - 1 <= m_alias_region_end - 1;
|
||||
return this->Contains(addr, size) && m_region_starts[RegionType_Alias] <= addr && addr + size - 1 <= m_region_ends[RegionType_Alias] - 1;
|
||||
}
|
||||
|
||||
bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const {
|
||||
@ -311,7 +318,7 @@ namespace ams::kern {
|
||||
R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr));
|
||||
}
|
||||
|
||||
Result CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const;
|
||||
Result CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const;
|
||||
Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const;
|
||||
Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const;
|
||||
Result CheckMemoryState(size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const {
|
||||
@ -321,6 +328,8 @@ namespace ams::kern {
|
||||
R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr));
|
||||
}
|
||||
|
||||
bool CanReadWriteDebugMemory(KProcessAddress addr, size_t size, bool force_debug_prod);
|
||||
|
||||
Result LockMemoryAndOpen(KPageGroup *out_pg, KPhysicalAddress *out_paddr, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr);
|
||||
Result UnlockMemory(KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr, const KPageGroup *pg);
|
||||
|
||||
@ -328,7 +337,7 @@ namespace ams::kern {
|
||||
|
||||
Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const;
|
||||
|
||||
Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm);
|
||||
Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, const KPageProperties &properties);
|
||||
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);
|
||||
@ -387,8 +396,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 MapInsecureMemory(KProcessAddress address, size_t size);
|
||||
Result UnmapInsecureMemory(KProcessAddress address, size_t size);
|
||||
Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size);
|
||||
Result UnmapInsecurePhysicalMemory(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));
|
||||
@ -414,7 +423,7 @@ namespace ams::kern {
|
||||
Result InvalidateProcessDataCache(KProcessAddress address, size_t size);
|
||||
Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size);
|
||||
|
||||
Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size);
|
||||
Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod);
|
||||
Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state);
|
||||
|
||||
Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size);
|
||||
@ -479,24 +488,30 @@ namespace ams::kern {
|
||||
}
|
||||
public:
|
||||
KProcessAddress GetAddressSpaceStart() const { return m_address_space_start; }
|
||||
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 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 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_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 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 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_heap_region_start) + m_mapped_physical_memory_size;
|
||||
return (m_current_heap_end - m_region_starts[RegionType_Heap]) + m_mapped_physical_memory_size;
|
||||
}
|
||||
|
||||
size_t GetCodeSize() const;
|
||||
|
@ -206,6 +206,10 @@ namespace ams::kern {
|
||||
return m_capabilities.IsPermittedDebug();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebugProd() const {
|
||||
return m_capabilities.CanForceDebugProd();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebug() const {
|
||||
return m_capabilities.CanForceDebug();
|
||||
}
|
||||
@ -360,7 +364,7 @@ namespace ams::kern {
|
||||
R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
|
||||
}
|
||||
|
||||
Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s32 value, s64 timeout) {
|
||||
Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s64 value, s64 timeout) {
|
||||
R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
|
||||
}
|
||||
|
||||
@ -374,7 +378,7 @@ namespace ams::kern {
|
||||
|
||||
/* Update the current page table. */
|
||||
if (next_process) {
|
||||
next_process->GetPageTable().Activate(next_process->GetProcessId());
|
||||
next_process->GetPageTable().Activate(next_process->GetSlabIndex(), next_process->GetProcessId());
|
||||
} else {
|
||||
Kernel::GetKernelPageTable().Activate();
|
||||
}
|
||||
|
@ -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);
|
||||
static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address);
|
||||
static bool ShouldIncreaseThreadResourceLimit();
|
||||
static void TurnOnCpu(u64 core_id, const ams::kern::init::KInitArguments *args);
|
||||
static size_t GetApplicationPoolSize();
|
||||
@ -69,6 +69,7 @@ namespace ams::kern {
|
||||
static NOINLINE void InitializePhase1Base(u64 seed);
|
||||
public:
|
||||
/* Initialization. */
|
||||
static NOINLINE void ConfigureKTargetSystem();
|
||||
static NOINLINE void InitializePhase1();
|
||||
static NOINLINE void InitializePhase2();
|
||||
static NOINLINE u32 GetCreateProcessMemoryPool();
|
||||
|
@ -24,29 +24,36 @@ namespace ams::kern {
|
||||
friend class KSystemControlBase;
|
||||
friend class KSystemControl;
|
||||
private:
|
||||
static inline constinit bool s_is_debug_mode;
|
||||
static inline constinit bool s_enable_debug_logging;
|
||||
static inline constinit bool s_enable_user_exception_handlers;
|
||||
static inline constinit bool s_enable_debug_memory_fill;
|
||||
static inline constinit bool s_enable_user_pmu_access;
|
||||
static inline constinit bool s_enable_kernel_debugging;
|
||||
static inline constinit bool s_enable_dynamic_resource_limits;
|
||||
struct KTargetSystemData {
|
||||
bool is_debug_mode;
|
||||
bool enable_debug_logging;
|
||||
bool enable_user_exception_handlers;
|
||||
bool enable_debug_memory_fill;
|
||||
bool enable_user_pmu_access;
|
||||
bool enable_kernel_debugging;
|
||||
bool enable_dynamic_resource_limits;
|
||||
};
|
||||
private:
|
||||
static ALWAYS_INLINE void SetIsDebugMode(bool en) { s_is_debug_mode = en; }
|
||||
static ALWAYS_INLINE void EnableDebugLogging(bool en) { s_enable_debug_logging = en; }
|
||||
static ALWAYS_INLINE void EnableUserExceptionHandlers(bool en) { s_enable_user_exception_handlers = en; }
|
||||
static ALWAYS_INLINE void EnableDebugMemoryFill(bool en) { s_enable_debug_memory_fill = en; }
|
||||
static ALWAYS_INLINE void EnableUserPmuAccess(bool en) { s_enable_user_pmu_access = en; }
|
||||
static ALWAYS_INLINE void EnableKernelDebugging(bool en) { s_enable_kernel_debugging = en; }
|
||||
static ALWAYS_INLINE void EnableDynamicResourceLimits(bool en) { s_enable_dynamic_resource_limits = en; }
|
||||
static inline constinit bool s_is_initialized = false;
|
||||
static inline constinit const volatile KTargetSystemData s_data = {
|
||||
.is_debug_mode = true,
|
||||
.enable_debug_logging = true,
|
||||
.enable_user_exception_handlers = true,
|
||||
.enable_debug_memory_fill = true,
|
||||
.enable_user_pmu_access = true,
|
||||
.enable_kernel_debugging = true,
|
||||
.enable_dynamic_resource_limits = false,
|
||||
};
|
||||
private:
|
||||
static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; }
|
||||
public:
|
||||
static ALWAYS_INLINE bool IsDebugMode() { return s_is_debug_mode; }
|
||||
static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_enable_debug_logging; }
|
||||
static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_enable_user_exception_handlers; }
|
||||
static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_enable_debug_memory_fill; }
|
||||
static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_enable_user_pmu_access; }
|
||||
static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_enable_kernel_debugging; }
|
||||
static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_enable_dynamic_resource_limits; }
|
||||
static ALWAYS_INLINE bool IsDebugMode() { return s_is_initialized && s_data.is_debug_mode; }
|
||||
static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_is_initialized && s_data.enable_debug_logging; }
|
||||
static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_is_initialized && s_data.enable_user_exception_handlers; }
|
||||
static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_is_initialized && s_data.enable_debug_memory_fill; }
|
||||
static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_is_initialized && s_data.enable_user_pmu_access; }
|
||||
static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_is_initialized && s_data.enable_kernel_debugging; }
|
||||
static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_is_initialized && s_data.enable_dynamic_resource_limits; }
|
||||
};
|
||||
|
||||
}
|
@ -48,6 +48,22 @@ namespace ams::kern {
|
||||
KProcess *GetOwner() const { return m_owner; }
|
||||
KProcessAddress GetSourceAddress() { return m_address; }
|
||||
size_t GetSize() const { return m_is_initialized ? GetReference(m_page_group).GetNumPages() * PageSize : 0; }
|
||||
|
||||
constexpr uintptr_t GetHint() const {
|
||||
/* Get memory size. */
|
||||
const size_t size = this->GetSize();
|
||||
|
||||
/* TODO: Is this architecture specific? */
|
||||
if (size >= 2_MB) {
|
||||
return GetInteger(m_address) & (2_MB - 1);
|
||||
} else if (size >= 64_KB) {
|
||||
return GetInteger(m_address) & (64_KB - 1);
|
||||
} else if (size >= 4_KB) {
|
||||
return GetInteger(m_address) & (4_KB - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ endif
|
||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
||||
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto
|
||||
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
||||
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||
|
||||
SOURCES += $(foreach v,$(call ALL_SOURCE_DIRS,../libvapours/source),$(if $(findstring ../libvapours/source/sdmmc,$v),,$v))
|
||||
|
@ -79,6 +79,12 @@ namespace ams::kern::arch::arm {
|
||||
|
||||
/* Setup all interrupt lines. */
|
||||
SetupInterruptLines(core_id);
|
||||
|
||||
/* Clear pointers, if needed. */
|
||||
if (core_id == 0) {
|
||||
m_gicd = nullptr;
|
||||
m_gicc = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void KInterruptController::SaveCoreLocal(LocalState *state) const {
|
||||
|
@ -100,6 +100,8 @@ namespace ams::kern::arch::arm64 {
|
||||
u32 insn_value = 0;
|
||||
if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_value), reinterpret_cast<u32 *>(context->pc), sizeof(insn_value))) {
|
||||
insn = insn_value;
|
||||
} else if (KTargetSystem::IsDebugMode() && (context->pc & 3) == 0 && UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccess(std::addressof(insn_value), reinterpret_cast<u32 *>(context->pc))) {
|
||||
insn = insn_value;
|
||||
} else {
|
||||
insn = 0;
|
||||
}
|
||||
@ -112,33 +114,6 @@ namespace ams::kern::arch::arm64 {
|
||||
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)
|
||||
@ -223,6 +198,13 @@ 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;
|
||||
|
@ -15,6 +15,28 @@
|
||||
*/
|
||||
#include <mesosphere.hpp>
|
||||
|
||||
/* <stratosphere/rocrt/rocrt.hpp> */
|
||||
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 {
|
||||
@ -365,7 +387,7 @@ namespace ams::kern::arch::arm64 {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
/* Set the watchkpoint. */
|
||||
/* Set the watchpoint. */
|
||||
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;
|
||||
@ -623,11 +645,6 @@ 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);
|
||||
@ -637,36 +654,32 @@ namespace ams::kern::arch::arm64 {
|
||||
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
|
||||
}
|
||||
|
||||
if (temp_32 == 0) {
|
||||
/* Module is dynamically loaded by rtld. */
|
||||
/* Locate .dyn using rocrt::ModuleHeader. */
|
||||
{
|
||||
/* Determine the ModuleHeader offset. */
|
||||
u32 mod_offset;
|
||||
if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) {
|
||||
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
|
||||
}
|
||||
if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset)) {
|
||||
|
||||
/* Read the signature. */
|
||||
constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature);
|
||||
if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + SignatureFieldOffset)) {
|
||||
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
|
||||
}
|
||||
if (temp_32 != 0x30444F4D) { /* MOD0 */
|
||||
|
||||
/* Check that the module signature is expected. */
|
||||
if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */
|
||||
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
|
||||
}
|
||||
if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + sizeof(u32))) {
|
||||
|
||||
/* 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)) {
|
||||
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. */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,101 +27,70 @@ namespace ams::kern::arch::arm64 {
|
||||
m_table = static_cast<L1PageTableEntry *>(tb);
|
||||
m_is_kernel = false;
|
||||
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<PageTableEntry *>(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<PageTableEntry>(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. */
|
||||
++level_entries[level];
|
||||
if (!util::IsAligned(reinterpret_cast<uintptr_t>(++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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L1PageTableEntry *KPageTableImpl::Finalize() {
|
||||
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<KPhysicalAddress>;
|
||||
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<KPhysicalAddress>;
|
||||
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<KPhysicalAddress>;
|
||||
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->phys_addr = Null<KPhysicalAddress>;
|
||||
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;
|
||||
*out_entry = {};
|
||||
*out_context = {};
|
||||
|
||||
/* Validate that we can read the actual entry. */
|
||||
const size_t l0_index = GetL0Index(address);
|
||||
@ -138,124 +107,78 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the entry. */
|
||||
const bool valid = this->ExtractL1Entry(out_entry, out_context, this->GetL1Entry(address), address);
|
||||
/* Get the L1 entry, and check if it's a table. */
|
||||
out_context->level_entries[EntryLevel_L1] = this->GetL1Entry(address);
|
||||
if (out_context->level_entries[EntryLevel_L1]->IsMappedTable()) {
|
||||
/* Get the L2 entry, and check if it's a table. */
|
||||
out_context->level_entries[EntryLevel_L2] = this->GetL2EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L1]->GetTable()), address);
|
||||
if (out_context->level_entries[EntryLevel_L2]->IsMappedTable()) {
|
||||
/* Get the L3 entry. */
|
||||
out_context->level_entries[EntryLevel_L3] = this->GetL3EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L2]->GetTable()), address);
|
||||
|
||||
/* Update the context for next traversal. */
|
||||
switch (out_entry->block_size) {
|
||||
case L1ContiguousBlockSize:
|
||||
out_context->l1_entry += (L1ContiguousBlockSize / L1BlockSize) - GetContiguousL1Offset(address) / L1BlockSize;
|
||||
break;
|
||||
case L1BlockSize:
|
||||
out_context->l1_entry += 1;
|
||||
break;
|
||||
case L2ContiguousBlockSize:
|
||||
out_context->l1_entry += 1;
|
||||
out_context->l2_entry += (L2ContiguousBlockSize / L2BlockSize) - GetContiguousL2Offset(address) / L2BlockSize;
|
||||
break;
|
||||
case L2BlockSize:
|
||||
out_context->l1_entry += 1;
|
||||
out_context->l2_entry += 1;
|
||||
break;
|
||||
case L3ContiguousBlockSize:
|
||||
out_context->l1_entry += 1;
|
||||
out_context->l2_entry += 1;
|
||||
out_context->l3_entry += (L3ContiguousBlockSize / L3BlockSize) - GetContiguousL3Offset(address) / L3BlockSize;
|
||||
break;
|
||||
case L3BlockSize:
|
||||
out_context->l1_entry += 1;
|
||||
out_context->l2_entry += 1;
|
||||
out_context->l3_entry += 1;
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
/* It's either a page or not. */
|
||||
out_context->level = EntryLevel_L3;
|
||||
} else {
|
||||
/* Not a L2 table, so possibly an L2 block. */
|
||||
out_context->level = EntryLevel_L2;
|
||||
}
|
||||
} else {
|
||||
/* Not a L1 table, so possibly an L1 block. */
|
||||
out_context->level = EntryLevel_L1;
|
||||
}
|
||||
|
||||
return valid;
|
||||
/* Determine other fields. */
|
||||
const auto *pte = out_context->level_entries[out_context->level];
|
||||
|
||||
out_context->is_contiguous = pte->IsContiguous();
|
||||
|
||||
out_entry->sw_reserved_bits = pte->GetSoftwareReservedBits();
|
||||
out_entry->attr = 0;
|
||||
out_entry->phys_addr = this->GetBlock(pte, out_context->level) + this->GetOffset(address, out_context->level);
|
||||
out_entry->block_size = static_cast<size_t>(1) << (PageBits + LevelBits * out_context->level + 4 * out_context->is_contiguous);
|
||||
|
||||
return out_context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock();
|
||||
}
|
||||
|
||||
bool KPageTableImpl::ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const {
|
||||
bool valid = false;
|
||||
/* Advance entry. */
|
||||
auto *cur_pte = context->level_entries[context->level];
|
||||
auto *next_pte = reinterpret_cast<PageTableEntry *>(context->is_contiguous ? util::AlignDown(reinterpret_cast<uintptr_t>(cur_pte), BlocksPerContiguousBlock * sizeof(PageTableEntry)) + BlocksPerContiguousBlock * sizeof(PageTableEntry) : reinterpret_cast<uintptr_t>(cur_pte) + sizeof(PageTableEntry));
|
||||
|
||||
/* Check if we're not at the end of an L3 table. */
|
||||
if (!util::IsAligned(reinterpret_cast<uintptr_t>(context->l3_entry), PageSize)) {
|
||||
valid = this->ExtractL3Entry(out_entry, context, context->l3_entry, Null<KProcessAddress>);
|
||||
/* Set the pte. */
|
||||
context->level_entries[context->level] = next_pte;
|
||||
|
||||
switch (out_entry->block_size) {
|
||||
case L3ContiguousBlockSize:
|
||||
context->l3_entry += (L3ContiguousBlockSize / L3BlockSize);
|
||||
break;
|
||||
case L3BlockSize:
|
||||
context->l3_entry += 1;
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
} else if (!util::IsAligned(reinterpret_cast<uintptr_t>(context->l2_entry), PageSize)) {
|
||||
/* We're not at the end of an L2 table. */
|
||||
valid = this->ExtractL2Entry(out_entry, context, context->l2_entry, Null<KProcessAddress>);
|
||||
/* Advance appropriately. */
|
||||
while (context->level < EntryLevel_L1 && util::IsAligned(reinterpret_cast<uintptr_t>(context->level_entries[context->level]), PageSize)) {
|
||||
/* Advance the above table by one entry. */
|
||||
context->level_entries[context->level + 1]++;
|
||||
context->level = static_cast<EntryLevel>(util::ToUnderlying(context->level) + 1);
|
||||
}
|
||||
|
||||
switch (out_entry->block_size) {
|
||||
case L2ContiguousBlockSize:
|
||||
context->l2_entry += (L2ContiguousBlockSize / L2BlockSize);
|
||||
break;
|
||||
case L2BlockSize:
|
||||
context->l2_entry += 1;
|
||||
break;
|
||||
case L3ContiguousBlockSize:
|
||||
context->l2_entry += 1;
|
||||
context->l3_entry += (L3ContiguousBlockSize / L3BlockSize);
|
||||
break;
|
||||
case L3BlockSize:
|
||||
context->l2_entry += 1;
|
||||
context->l3_entry += 1;
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
} else {
|
||||
/* We need to update the l1 entry. */
|
||||
const size_t l1_index = context->l1_entry - m_table;
|
||||
if (l1_index < m_num_entries) {
|
||||
valid = this->ExtractL1Entry(out_entry, context, context->l1_entry, Null<KProcessAddress>);
|
||||
} else {
|
||||
/* Invalid, end traversal. */
|
||||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
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;
|
||||
/* Check if we've hit the end of the L1 table. */
|
||||
if (context->level == EntryLevel_L1) {
|
||||
if (context->level_entries[EntryLevel_L1] - static_cast<const PageTableEntry *>(m_table) >= m_num_entries) {
|
||||
*context = {};
|
||||
*out_entry = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (out_entry->block_size) {
|
||||
case L1ContiguousBlockSize:
|
||||
context->l1_entry += (L1ContiguousBlockSize / L1BlockSize);
|
||||
break;
|
||||
case L1BlockSize:
|
||||
context->l1_entry += 1;
|
||||
break;
|
||||
case L2ContiguousBlockSize:
|
||||
context->l1_entry += 1;
|
||||
context->l2_entry += (L2ContiguousBlockSize / L2BlockSize);
|
||||
break;
|
||||
case L2BlockSize:
|
||||
context->l1_entry += 1;
|
||||
context->l2_entry += 1;
|
||||
break;
|
||||
case L3ContiguousBlockSize:
|
||||
context->l1_entry += 1;
|
||||
context->l2_entry += 1;
|
||||
context->l3_entry += (L3ContiguousBlockSize / L3BlockSize);
|
||||
break;
|
||||
case L3BlockSize:
|
||||
context->l1_entry += 1;
|
||||
context->l2_entry += 1;
|
||||
context->l3_entry += 1;
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
/* We may have advanced to a new table, and if we have we should descend. */
|
||||
while (context->level > EntryLevel_L3 && context->level_entries[context->level]->IsMappedTable()) {
|
||||
context->level_entries[context->level - 1] = GetPointer<PageTableEntry>(GetPageTableVirtualAddress(context->level_entries[context->level]->GetTable()));
|
||||
context->level = static_cast<EntryLevel>(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<size_t>(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous);
|
||||
return context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock();
|
||||
}
|
||||
|
||||
bool KPageTableImpl::GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
|
||||
@ -274,32 +197,144 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to get from l1 table. */
|
||||
const L1PageTableEntry *l1_entry = this->GetL1Entry(address);
|
||||
if (l1_entry->IsBlock()) {
|
||||
*out = l1_entry->GetBlock() + GetL1Offset(address);
|
||||
return true;
|
||||
} else if (!l1_entry->IsTable()) {
|
||||
return false;
|
||||
/* Get the L1 entry, and check if it's a table. */
|
||||
const PageTableEntry *pte = this->GetL1Entry(address);
|
||||
EntryLevel level = EntryLevel_L1;
|
||||
if (pte->IsMappedTable()) {
|
||||
/* Get the L2 entry, and check if it's a table. */
|
||||
pte = this->GetL2EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address);
|
||||
level = EntryLevel_L2;
|
||||
if (pte->IsMappedTable()) {
|
||||
pte = this->GetL3EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address);
|
||||
level = EntryLevel_L3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to get from l2 table. */
|
||||
const L2PageTableEntry *l2_entry = this->GetL2Entry(l1_entry, address);
|
||||
if (l2_entry->IsBlock()) {
|
||||
*out = l2_entry->GetBlock() + GetL2Offset(address);
|
||||
return true;
|
||||
} else if (!l2_entry->IsTable()) {
|
||||
return false;
|
||||
const bool is_block = level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock();
|
||||
if (is_block) {
|
||||
*out = this->GetBlock(pte, level) + this->GetOffset(address, level);
|
||||
} else {
|
||||
*out = Null<KPhysicalAddress>;
|
||||
}
|
||||
|
||||
/* Try to get from l3 table. */
|
||||
const L3PageTableEntry *l3_entry = this->GetL3Entry(l2_entry, address);
|
||||
if (l3_entry->IsBlock()) {
|
||||
*out = l3_entry->GetBlock() + GetL3Offset(address);
|
||||
return true;
|
||||
return is_block;
|
||||
}
|
||||
|
||||
bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) {
|
||||
/* 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<PageTableEntry *>(util::AlignDown(reinterpret_cast<uintptr_t>(context->level_entries[context->level]), BlocksPerTable * sizeof(PageTableEntry)));
|
||||
const KPhysicalAddress phys_addr = util::AlignDown(GetBlock(pte, context->level), GetBlockSize(static_cast<EntryLevel>(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);
|
||||
|
||||
/* Update our context. */
|
||||
context->is_contiguous = false;
|
||||
context->level = static_cast<EntryLevel>(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<PageTableEntry *>(util::AlignDown(reinterpret_cast<uintptr_t>(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);
|
||||
}
|
||||
|
||||
/* Update our context. */
|
||||
context->level_entries[context->level] = pte;
|
||||
context->is_contiguous = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) 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<PageTableEntry *>(util::AlignDown(reinterpret_cast<uintptr_t>(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{});
|
||||
}
|
||||
|
||||
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<EntryLevel>(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);
|
||||
|
||||
|
||||
context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level);
|
||||
}
|
||||
|
||||
entry->sw_reserved_bits = 0;
|
||||
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<size_t>(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous);
|
||||
}
|
||||
|
||||
void KPageTableImpl::Dump(uintptr_t start, size_t size) const {
|
||||
|
@ -21,6 +21,15 @@ namespace ams::kern::arch::arm64 {
|
||||
void UserModeThreadStarter();
|
||||
void SupervisorModeThreadStarter();
|
||||
|
||||
void InvokeSupervisorModeThread(uintptr_t argument, uintptr_t entrypoint) {
|
||||
/* Invoke the function. */
|
||||
using SupervisorModeFunctionType = void (*)(uintptr_t);
|
||||
reinterpret_cast<SupervisorModeFunctionType>(entrypoint)(argument);
|
||||
|
||||
/* Wait forever. */
|
||||
AMS_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
void OnThreadStart() {
|
||||
MESOSPHERE_ASSERT(!KInterruptManager::AreInterruptsEnabled());
|
||||
/* Send KDebug event for this thread's creation. */
|
||||
|
@ -126,6 +126,20 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv:
|
||||
/* Just load and store a u64. */
|
||||
ldtr x2, [x1]
|
||||
str x2, [x0]
|
||||
|
||||
/* We're done. */
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv
|
||||
@ -140,6 +154,21 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv:
|
||||
mov x0, #1
|
||||
ret
|
||||
|
||||
/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv
|
||||
.type _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, %function
|
||||
.balign 0x10
|
||||
_ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv:
|
||||
/* 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::CopyStringFromUser(void *dst, const void *src, size_t size) */
|
||||
.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits
|
||||
.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* 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
|
@ -68,7 +68,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
|
||||
|
||||
/* Check if our disable count allows us to call SVCs. */
|
||||
mrs x10, tpidrro_el0
|
||||
ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)]
|
||||
add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)
|
||||
ldtrh w10, [x10]
|
||||
cbz w10, 1f
|
||||
|
||||
/* It might not, so check the stack params to see if we must not allow the SVC. */
|
||||
@ -352,7 +353,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
|
||||
|
||||
/* Check if our disable count allows us to call SVCs. */
|
||||
mrs x10, tpidrro_el0
|
||||
ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)]
|
||||
add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)
|
||||
ldtrh w10, [x10]
|
||||
cbz w10, 1f
|
||||
|
||||
/* It might not, so check the stack params to see if we must not allow the SVC. */
|
||||
|
@ -36,6 +36,10 @@ namespace ams::kern::svc {
|
||||
/* Declare special prototype for (unsupported) CallCallSecureMonitor64From32. */
|
||||
void CallCallSecureMonitor64From32();
|
||||
|
||||
/* Declare special prototypes for WaitForAddress. */
|
||||
void CallWaitForAddress64();
|
||||
void CallWaitForAddress64From32();
|
||||
|
||||
namespace {
|
||||
|
||||
#ifndef MESOSPHERE_USE_STUBBED_SVC_TABLES
|
||||
@ -81,6 +85,8 @@ namespace ams::kern::svc {
|
||||
|
||||
table[svc::SvcId_CallSecureMonitor] = CallCallSecureMonitor64From32;
|
||||
|
||||
table[svc::SvcId_WaitForAddress] = CallWaitForAddress64From32;
|
||||
|
||||
return table;
|
||||
}();
|
||||
|
||||
@ -97,6 +103,8 @@ namespace ams::kern::svc {
|
||||
|
||||
table[svc::SvcId_ReturnFromException] = CallReturnFromException64;
|
||||
|
||||
table[svc::SvcId_WaitForAddress] = CallWaitForAddress64;
|
||||
|
||||
return table;
|
||||
}();
|
||||
|
||||
@ -142,10 +150,10 @@ namespace ams::kern::svc {
|
||||
/* Get the target firmware. */
|
||||
const auto target_fw = kern::GetTargetFirmware();
|
||||
|
||||
/* 10.0.0 broke the ABI for QueryIoMapping. */
|
||||
/* 10.0.0 broke the ABI for QueryIoMapping, and renamed it to QueryMemoryMapping. */
|
||||
if (target_fw < TargetFirmware_10_0_0) {
|
||||
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); }
|
||||
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); }
|
||||
}
|
||||
|
||||
/* 6.0.0 broke the ABI for GetFutureThreadInfo, and renamed it to GetDebugFutureThreadInfo. */
|
||||
|
@ -31,7 +31,6 @@ namespace ams::kern::board::nintendo::nx {
|
||||
/* Struct representing registers saved on wake/sleep. */
|
||||
class SavedSystemRegisters {
|
||||
private:
|
||||
u64 ttbr0_el1;
|
||||
u64 elr_el1;
|
||||
u64 sp_el0;
|
||||
u64 spsr_el1;
|
||||
@ -90,7 +89,6 @@ namespace ams::kern::board::nintendo::nx {
|
||||
|
||||
void SavedSystemRegisters::Save() {
|
||||
/* Save system registers. */
|
||||
this->ttbr0_el1 = cpu::GetTtbr0El1();
|
||||
this->tpidr_el0 = cpu::GetTpidrEl0();
|
||||
this->elr_el1 = cpu::GetElrEl1();
|
||||
this->sp_el0 = cpu::GetSpEl0();
|
||||
@ -405,7 +403,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
cpu::EnsureInstructionConsistency();
|
||||
|
||||
/* Restore system registers. */
|
||||
cpu::SetTtbr0El1 (this->ttbr0_el1);
|
||||
cpu::SetTtbr0El1 (KPageTable::GetKernelTtbr0());
|
||||
cpu::SetTpidrEl0 (this->tpidr_el0);
|
||||
cpu::SetElrEl1 (this->elr_el1);
|
||||
cpu::SetSpEl0 (this->sp_el0);
|
||||
|
@ -26,7 +26,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
constexpr size_t SecureSizeMax = util::AlignDown(512_MB - 1, SecureAlignment);
|
||||
|
||||
/* Global variables for panic. */
|
||||
constinit bool g_call_smc_on_panic;
|
||||
constinit const volatile bool g_call_smc_on_panic = false;
|
||||
|
||||
/* Global variables for secure memory. */
|
||||
constinit KSpinLock g_secure_applet_lock;
|
||||
@ -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;
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(smc::init::ReadWriteRegister(&config_value, MemoryControllerConfigurationRegister, 0, 0));
|
||||
smc::init::ReadWriteRegister(std::addressof(config_value), MemoryControllerConfigurationRegister, 0, 0);
|
||||
return static_cast<size_t>(config_value & 0x3FFF) << 20;
|
||||
}
|
||||
|
||||
@ -387,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<smc::SmcId_Supervisor, false>(core_id, entrypoint, arg)) == 0);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<smc::SmcId_Supervisor>(core_id, entrypoint, arg)) == 0);
|
||||
}
|
||||
|
||||
/* Randomness for Initialization. */
|
||||
@ -401,34 +401,67 @@ namespace ams::kern::board::nintendo::nx {
|
||||
}
|
||||
|
||||
/* System Initialization. */
|
||||
void KSystemControl::InitializePhase1() {
|
||||
void KSystemControl::ConfigureKTargetSystem() {
|
||||
/* Configure KTargetSystem. */
|
||||
volatile auto *ts = const_cast<volatile KTargetSystem::KTargetSystemData *>(std::addressof(KTargetSystem::s_data));
|
||||
{
|
||||
/* Set IsDebugMode. */
|
||||
{
|
||||
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
|
||||
ts->is_debug_mode = GetConfigBool(smc::ConfigItem::IsDebugMode);
|
||||
|
||||
/* If debug mode, we want to initialize uart logging. */
|
||||
KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode());
|
||||
ts->enable_debug_logging = ts->is_debug_mode;
|
||||
}
|
||||
|
||||
/* Set Kernel Configuration. */
|
||||
{
|
||||
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
|
||||
|
||||
KTargetSystem::EnableDebugMemoryFill(kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>());
|
||||
KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>());
|
||||
KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>());
|
||||
KTargetSystem::EnableUserPmuAccess(kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>());
|
||||
ts->enable_debug_memory_fill = kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>();
|
||||
ts->enable_user_exception_handlers = kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>();
|
||||
ts->enable_dynamic_resource_limits = !kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>();
|
||||
ts->enable_user_pmu_access = kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>();
|
||||
|
||||
g_call_smc_on_panic = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
|
||||
/* Configure call smc on panic. */
|
||||
*const_cast<volatile bool *>(std::addressof(g_call_smc_on_panic)) = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
|
||||
}
|
||||
|
||||
/* Set Kernel Debugging. */
|
||||
{
|
||||
/* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */
|
||||
/* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */
|
||||
KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification));
|
||||
ts->enable_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<smc::KernelConfiguration::DebugFillMemory>());
|
||||
MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserExceptionHandlersEnabled() == kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>());
|
||||
MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled() == !kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>());
|
||||
MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserPmuAccessEnabled() == kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>());
|
||||
|
||||
MESOSPHERE_ABORT_UNLESS(g_call_smc_on_panic == kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>());
|
||||
}
|
||||
|
||||
/* Check Kernel Debugging. */
|
||||
{
|
||||
MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsKernelDebuggingEnabled() == GetConfigBool(smc::ConfigItem::DisableProgramVerification));
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,19 +623,15 @@ namespace ams::kern::board::nintendo::nx {
|
||||
for (size_t i = 0; i < RebootPayloadSize / sizeof(u32); ++i) {
|
||||
GetPointer<volatile u32>(iram_address)[i] = GetPointer<volatile u32>(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::Panic(0xF00);
|
||||
smc::ShowError(0xF00);
|
||||
}
|
||||
|
||||
AMS_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||
enum FunctionId : u32 {
|
||||
FunctionId_GetConfig = 0xC3000004,
|
||||
FunctionId_GenerateRandomBytes = 0xC3000005,
|
||||
FunctionId_Panic = 0xC3000006,
|
||||
FunctionId_ShowError = 0xC3000006,
|
||||
FunctionId_ConfigureCarveout = 0xC3000007,
|
||||
FunctionId_ReadWriteRegister = 0xC3000008,
|
||||
|
||||
@ -51,122 +51,187 @@ 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<u32>(config_item) } };
|
||||
|
||||
/* Call into the secure monitor. */
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* If successful, copy the output. */
|
||||
const bool success = static_cast<SmcResult>(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<u32>(config_item), 0, value } };
|
||||
|
||||
/* Call into the secure monitor. */
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* Return whether the call was successful. */
|
||||
return static_cast<SmcResult>(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<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* Unconditionally write the output. */
|
||||
*out = static_cast<u32>(args.r[1]);
|
||||
|
||||
/* Return whether the call was successful. */
|
||||
return static_cast<SmcResult>(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<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* If successful, copy the output. */
|
||||
const bool success = static_cast<SmcResult>(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<u64>(which), static_cast<u64>(address), static_cast<u64>(size) } };
|
||||
|
||||
/* Call into the secure monitor. */
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* Return whether the call was successful. */
|
||||
return static_cast<SmcResult>(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<SmcId_Supervisor>(args.r);
|
||||
|
||||
/* Return whether the call was successful. */
|
||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||
}
|
||||
|
||||
void CallSecureMonitorFromUserImpl(ams::svc::lp64::SecureMonitorArguments *args) {
|
||||
/* Call into the secure monitor. */
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_User>(args->r);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* SMC functionality needed for init. */
|
||||
namespace init {
|
||||
|
||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast<u32>(config_item) } };
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, false>(args.r);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
||||
|
||||
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
||||
out[i] = args.r[1 + i];
|
||||
}
|
||||
/* Ensure we successfully get the config. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(TryGetConfigImpl(out, num_qwords, config_item));
|
||||
}
|
||||
|
||||
void GenerateRandomBytes(void *dst, size_t size) {
|
||||
/* Call SmcGenerateRandomBytes() */
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } };
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0]));
|
||||
/* Check that the size is valid. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax);
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, false>(args.r);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
||||
|
||||
/* Copy output. */
|
||||
std::memcpy(dst, std::addressof(args.r[1]), size);
|
||||
/* Ensure we successfully generate the random bytes. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size));
|
||||
}
|
||||
|
||||
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<SmcId_Supervisor, false>(args.r);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
||||
|
||||
*out = args.r[1];
|
||||
|
||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||
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 TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast<u32>(config_item) } };
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
if (AMS_UNLIKELY(static_cast<SmcResult>(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;
|
||||
/* Get the config. */
|
||||
return TryGetConfigImpl(out, num_qwords, config_item);
|
||||
}
|
||||
|
||||
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) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast<u32>(config_item), 0, value } };
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
|
||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||
/* Set the config. */
|
||||
return SetConfigImpl(config_item, value);
|
||||
}
|
||||
|
||||
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } };
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
|
||||
*out = static_cast<u32>(args.r[1]);
|
||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||
/* Access the register. */
|
||||
return ReadWriteRegisterImpl(out, address, mask, value);
|
||||
}
|
||||
|
||||
void ConfigureCarveout(size_t which, uintptr_t address, size_t size) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast<u64>(which), static_cast<u64>(address), static_cast<u64>(size) } };
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
|
||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
||||
/* Ensure that we successfully configure the carveout. */
|
||||
MESOSPHERE_ABORT_UNLESS(ConfigureCarveoutImpl(which, address, size));
|
||||
}
|
||||
|
||||
void GenerateRandomBytes(void *dst, size_t size) {
|
||||
/* Setup for call. */
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } };
|
||||
MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0]));
|
||||
/* Check that the size is valid. */
|
||||
MESOSPHERE_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax);
|
||||
|
||||
/* Make call. */
|
||||
{
|
||||
KScopedInterruptDisable intr_disable;
|
||||
KScopedSpinLock lk(g_generate_random_lock);
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
}
|
||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
||||
/* Acquire the exclusive right to generate random bytes. */
|
||||
KScopedSpinLock lk(g_generate_random_lock);
|
||||
|
||||
/* Copy output. */
|
||||
std::memcpy(dst, std::addressof(args.r[1]), size);
|
||||
/* Ensure we successfully generate the random bytes. */
|
||||
MESOSPHERE_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size));
|
||||
}
|
||||
|
||||
void NORETURN Panic(u32 color) {
|
||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_Panic, color } };
|
||||
void ShowError(u32 color) {
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
||||
|
||||
AMS_INFINITE_LOOP();
|
||||
/* Ensure we successfully show the error. */
|
||||
MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color));
|
||||
}
|
||||
|
||||
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) {
|
||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_User, true>(args->r);
|
||||
/* Disable interrupts. */
|
||||
KScopedInterruptDisable di;
|
||||
|
||||
/* Perform the call. */
|
||||
CallSecureMonitorFromUserImpl(args);
|
||||
}
|
||||
|
||||
}
|
@ -98,9 +98,10 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||
};
|
||||
|
||||
enum UserRebootType {
|
||||
UserRebootType_None = 0,
|
||||
UserRebootType_ToRcm = 1,
|
||||
UserRebootType_ToPayload = 2,
|
||||
UserRebootType_None = 0,
|
||||
UserRebootType_ToRcm = 1,
|
||||
UserRebootType_ToPayload = 2,
|
||||
UserRebootType_ToFatalError = 3,
|
||||
};
|
||||
|
||||
void GenerateRandomBytes(void *dst, size_t size);
|
||||
@ -111,7 +112,7 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||
|
||||
bool SetConfig(ConfigItem config_item, u64 value);
|
||||
|
||||
void NORETURN Panic(u32 color);
|
||||
void ShowError(u32 color);
|
||||
|
||||
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args);
|
||||
|
||||
@ -119,7 +120,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);
|
||||
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
||||
void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
||||
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,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, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront)));
|
||||
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(unreserve_pg), unreserved_size / PageSize, 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront)));
|
||||
|
||||
/* Add the previously reserved pages. */
|
||||
if (src_pool == dst_pool && binary_pages != 0) {
|
||||
@ -173,7 +173,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<size_t>(params.code_num_pages), KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront)));
|
||||
MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(workaround_pg), static_cast<size_t>(params.code_num_pages), 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront)));
|
||||
|
||||
/* Copy data from the working page group to the usable one. */
|
||||
auto work_it = pg.begin();
|
||||
|
@ -23,6 +23,10 @@ namespace ams::kern {
|
||||
return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool ReadFromUser(s64 *out, KProcessAddress address) {
|
||||
return UserspaceAccess::CopyMemoryFromUserSize64Bit(out, GetVoidPointer(address));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool DecrementIfLessThan(s32 *out, KProcessAddress address, s32 value) {
|
||||
/* NOTE: If scheduler lock is not held here, interrupt disable is required. */
|
||||
/* KScopedInterruptDisable di; */
|
||||
@ -279,4 +283,51 @@ namespace ams::kern {
|
||||
R_RETURN(cur_thread->GetWaitResult());
|
||||
}
|
||||
|
||||
Result KAddressArbiter::WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout) {
|
||||
/* Prepare to wait. */
|
||||
KThread *cur_thread = GetCurrentThreadPointer();
|
||||
KHardwareTimer *timer;
|
||||
ThreadQueueImplForKAddressArbiter wait_queue(std::addressof(m_tree));
|
||||
|
||||
{
|
||||
KScopedSchedulerLockAndSleep slp(std::addressof(timer), cur_thread, timeout);
|
||||
|
||||
/* Check that the thread isn't terminating. */
|
||||
if (cur_thread->IsTerminationRequested()) {
|
||||
slp.CancelSleep();
|
||||
R_THROW(svc::ResultTerminationRequested());
|
||||
}
|
||||
|
||||
/* Read the value from userspace. */
|
||||
s64 user_value;
|
||||
if (!ReadFromUser(std::addressof(user_value), addr)) {
|
||||
slp.CancelSleep();
|
||||
R_THROW(svc::ResultInvalidCurrentMemory());
|
||||
}
|
||||
|
||||
/* Check that the value is equal. */
|
||||
if (value != user_value) {
|
||||
slp.CancelSleep();
|
||||
R_THROW(svc::ResultInvalidState());
|
||||
}
|
||||
|
||||
/* Check that the timeout is non-zero. */
|
||||
if (timeout == 0) {
|
||||
slp.CancelSleep();
|
||||
R_THROW(svc::ResultTimedOut());
|
||||
}
|
||||
|
||||
/* Set the arbiter. */
|
||||
cur_thread->SetAddressArbiter(std::addressof(m_tree), addr);
|
||||
m_tree.insert(*cur_thread);
|
||||
|
||||
/* Wait for the thread to finish. */
|
||||
wait_queue.SetHardwareTimer(timer);
|
||||
cur_thread->BeginWait(std::addressof(wait_queue));
|
||||
}
|
||||
|
||||
/* Get the wait result. */
|
||||
R_RETURN(cur_thread->GetWaitResult());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,24 @@ namespace ams::kern {
|
||||
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
||||
};
|
||||
|
||||
constexpr u8 FlagsToAddressSpaceWidthTable[4] = {
|
||||
32, 36, 32, 39
|
||||
};
|
||||
|
||||
constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag flags) {
|
||||
/* Convert the input flags to an array index. */
|
||||
const size_t idx = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask) >> ams::svc::CreateProcessFlag_AddressSpaceShift;
|
||||
MESOSPHERE_ABORT_UNLESS(idx < sizeof(FlagsToAddressSpaceWidthTable));
|
||||
|
||||
/* Return the width. */
|
||||
return FlagsToAddressSpaceWidthTable[idx];
|
||||
}
|
||||
|
||||
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32Bit) == 32);
|
||||
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated) == 36);
|
||||
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) == 32);
|
||||
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64Bit) == 39);
|
||||
|
||||
KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
|
||||
for (auto &info : AddressSpaceInfos) {
|
||||
if (info.GetWidth() == width && info.GetType() == type) {
|
||||
@ -48,12 +66,12 @@ namespace ams::kern {
|
||||
|
||||
}
|
||||
|
||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
|
||||
return GetAddressSpaceInfo(width, type).GetAddress();
|
||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress();
|
||||
}
|
||||
|
||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
|
||||
return GetAddressSpaceInfo(width, type).GetSize();
|
||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize();
|
||||
}
|
||||
|
||||
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
||||
|
@ -184,6 +184,11 @@ 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<u32>(type)], perm));
|
||||
@ -257,7 +262,14 @@ namespace ams::kern {
|
||||
/* Validate. */
|
||||
R_UNLESS(cap.Get<DebugFlags::Reserved>() == 0, svc::ResultReservedUsed());
|
||||
|
||||
u32 total = 0;
|
||||
if (cap.Get<DebugFlags::AllowDebug>()) { ++total; }
|
||||
if (cap.Get<DebugFlags::ForceDebugProd>()) { ++total; }
|
||||
if (cap.Get<DebugFlags::ForceDebug>()) { ++total; }
|
||||
R_UNLESS(total <= 1, svc::ResultInvalidCombination());
|
||||
|
||||
m_debug_capabilities.Set<DebugFlags::AllowDebug>(cap.Get<DebugFlags::AllowDebug>());
|
||||
m_debug_capabilities.Set<DebugFlags::ForceDebugProd>(cap.Get<DebugFlags::ForceDebugProd>());
|
||||
m_debug_capabilities.Set<DebugFlags::ForceDebug>(cap.Get<DebugFlags::ForceDebug>());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ namespace ams::kern {
|
||||
R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions());
|
||||
new_sessions = cur_sessions + 1;
|
||||
} while (!m_num_sessions.CompareExchangeWeak<std::memory_order_relaxed>(cur_sessions, new_sessions));
|
||||
|
||||
}
|
||||
|
||||
/* Atomically update the peak session tracking. */
|
||||
@ -182,7 +181,6 @@ namespace ams::kern {
|
||||
R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions());
|
||||
new_sessions = cur_sessions + 1;
|
||||
} while (!m_num_sessions.CompareExchangeWeak<std::memory_order_relaxed>(cur_sessions, new_sessions));
|
||||
|
||||
}
|
||||
|
||||
/* Atomically update the peak session tracking. */
|
||||
|
@ -27,7 +27,8 @@ namespace ams::kern {
|
||||
|
||||
void KDebugBase::Initialize() {
|
||||
/* Clear the continue flags. */
|
||||
m_continue_flags = 0;
|
||||
m_continue_flags = 0;
|
||||
m_is_force_debug_prod = GetCurrentProcess().CanForceDebugProd();
|
||||
}
|
||||
|
||||
bool KDebugBase::Is64Bit() const {
|
||||
@ -120,8 +121,11 @@ namespace ams::kern {
|
||||
/* Read the memory. */
|
||||
if (info.GetSvcState() != ams::svc::MemoryState_Io) {
|
||||
/* The memory is normal memory. */
|
||||
R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size));
|
||||
R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size, this->IsForceDebugProd()));
|
||||
} else {
|
||||
/* Only allow IO memory to be read if not force debug prod. */
|
||||
R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* The memory is IO memory. */
|
||||
R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size, info.GetState()));
|
||||
}
|
||||
@ -269,6 +273,9 @@ namespace ams::kern {
|
||||
switch (state) {
|
||||
case KProcess::State_Created:
|
||||
case KProcess::State_Running:
|
||||
/* Created and running processes can only be debugged if the debugger is not ForceDebugProd. */
|
||||
R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidState());
|
||||
break;
|
||||
case KProcess::State_Crashed:
|
||||
break;
|
||||
case KProcess::State_CreatedAttached:
|
||||
@ -408,69 +415,6 @@ namespace ams::kern {
|
||||
/* Get the process pointer. */
|
||||
KProcess * const target = this->GetProcessUnsafe();
|
||||
|
||||
/* Detach from the process. */
|
||||
{
|
||||
/* Lock both ourselves and the target process. */
|
||||
KScopedLightLock state_lk(target->GetStateLock());
|
||||
KScopedLightLock list_lk(target->GetListLock());
|
||||
KScopedLightLock this_lk(m_lock);
|
||||
|
||||
/* Check that we're still attached. */
|
||||
if (this->IsAttached()) {
|
||||
/* Lock the scheduler. */
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* Get the process's state. */
|
||||
const KProcess::State state = target->GetState();
|
||||
|
||||
/* Check that the process is in a state where we can terminate it. */
|
||||
R_UNLESS(state != KProcess::State_Created, svc::ResultInvalidState());
|
||||
R_UNLESS(state != KProcess::State_CreatedAttached, svc::ResultInvalidState());
|
||||
|
||||
/* Decide on a new state for the process. */
|
||||
KProcess::State new_state;
|
||||
if (state == KProcess::State_RunningAttached) {
|
||||
/* If the process is running, transition it accordingly. */
|
||||
new_state = KProcess::State_Running;
|
||||
} else if (state == KProcess::State_DebugBreak) {
|
||||
/* If the process is debug breaked, transition it accordingly. */
|
||||
new_state = KProcess::State_Crashed;
|
||||
|
||||
/* Suspend all the threads in the process. */
|
||||
{
|
||||
auto end = target->GetThreadList().end();
|
||||
for (auto it = target->GetThreadList().begin(); it != end; ++it) {
|
||||
/* Request that we suspend the thread. */
|
||||
it->RequestSuspend(KThread::SuspendType_Debug);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Otherwise, don't transition. */
|
||||
new_state = state;
|
||||
}
|
||||
|
||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||
/* Clear single step on all threads. */
|
||||
{
|
||||
auto end = target->GetThreadList().end();
|
||||
for (auto it = target->GetThreadList().begin(); it != end; ++it) {
|
||||
it->ClearHardwareSingleStep();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Detach from the process. */
|
||||
target->ClearDebugObject(new_state);
|
||||
m_is_attached = false;
|
||||
|
||||
/* Close the initial reference opened to our process. */
|
||||
this->CloseProcess();
|
||||
|
||||
/* Clear our continue flags. */
|
||||
m_continue_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the process. */
|
||||
target->Terminate();
|
||||
|
||||
@ -962,7 +906,12 @@ namespace ams::kern {
|
||||
case ams::svc::DebugException_UndefinedInstruction:
|
||||
{
|
||||
MESOSPHERE_ASSERT(info->info.exception.exception_data_count == 1);
|
||||
out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0];
|
||||
/* Only save the instruction if the caller is not force debug prod. */
|
||||
if (this->IsForceDebugProd()) {
|
||||
out->info.exception.specific.undefined_instruction.insn = 0;
|
||||
} else {
|
||||
out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ams::svc::DebugException_BreakPoint:
|
||||
|
@ -79,29 +79,7 @@ namespace ams::kern {
|
||||
|
||||
/* Create a page group representing the segment. */
|
||||
KPageGroup segment_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer());
|
||||
if (size_t remaining_size = util::AlignUp(seg_size, PageSize); remaining_size != 0) {
|
||||
/* Find the pages whose data corresponds to the segment. */
|
||||
size_t cur_offset = 0;
|
||||
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 = seg_offset - cur_offset;
|
||||
const bool is_before = cur_offset <= seg_offset;
|
||||
cur_offset += cur_size;
|
||||
if (is_before && seg_offset < cur_offset) {
|
||||
/* It is, so add the block. */
|
||||
const size_t block_size = std::min<size_t>(cur_size - rel_diff, remaining_size);
|
||||
MESOSPHERE_R_ABORT_UNLESS(segment_pg.AddBlock(it->GetAddress() + rel_diff, block_size / PageSize));
|
||||
|
||||
/* Advance. */
|
||||
cur_offset = seg_offset + block_size;
|
||||
remaining_size -= block_size;
|
||||
seg_offset += block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
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. */
|
||||
{
|
||||
@ -215,37 +193,25 @@ namespace ams::kern {
|
||||
R_UNLESS(this->Is64Bit(), svc::ResultInvalidCombination());
|
||||
}
|
||||
|
||||
using ASType = KAddressSpaceInfo::Type;
|
||||
|
||||
const uintptr_t start_address = rx_address;
|
||||
const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size;
|
||||
const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32;
|
||||
const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall;
|
||||
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type);
|
||||
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type);
|
||||
const uintptr_t map_end = map_start + map_size;
|
||||
MESOSPHERE_ABORT_UNLESS(start_address == 0);
|
||||
|
||||
/* Default fields in parameter to zero. */
|
||||
*out = {};
|
||||
|
||||
/* Set fields in parameter. */
|
||||
out->code_address = map_start + start_address;
|
||||
out->code_address = 0;
|
||||
out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize;
|
||||
out->program_id = m_kip_header.GetProgramId();
|
||||
out->version = m_kip_header.GetVersion();
|
||||
out->flags = 0;
|
||||
out->reslimit = ams::svc::InvalidHandle;
|
||||
out->system_resource_num_pages = 0;
|
||||
MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize));
|
||||
|
||||
/* Copy name field. */
|
||||
m_kip_header.GetName(out->name, sizeof(out->name));
|
||||
|
||||
/* Apply ASLR, if needed. */
|
||||
if (enable_aslr) {
|
||||
const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment);
|
||||
out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment;
|
||||
out->flags |= ams::svc::CreateProcessFlag_EnableAslr;
|
||||
}
|
||||
|
||||
/* Apply other flags. */
|
||||
if (this->Is64Bit()) {
|
||||
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
|
||||
@ -255,10 +221,28 @@ 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. */
|
||||
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<ams::svc::CreateProcessFlag>(out->flags), as_type);
|
||||
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(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();
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,11 @@ namespace ams::kern {
|
||||
return "Unknown ";
|
||||
}
|
||||
|
||||
constexpr const char *GetMemoryPermissionString(const KMemoryInfo &info) {
|
||||
if (info.m_state == KMemoryState_Free) {
|
||||
constexpr const char *GetMemoryPermissionString(const KMemoryBlock &block) {
|
||||
if (block.GetState() == KMemoryState_Free) {
|
||||
return " ";
|
||||
} else {
|
||||
switch (info.m_permission) {
|
||||
switch (block.GetPermission()) {
|
||||
case KMemoryPermission_UserReadExecute:
|
||||
return "r-x";
|
||||
case KMemoryPermission_UserRead:
|
||||
@ -71,19 +71,19 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
|
||||
void DumpMemoryInfo(const KMemoryInfo &info) {
|
||||
const char *state = GetMemoryStateName(info.m_state);
|
||||
const char *perm = GetMemoryPermissionString(info);
|
||||
const uintptr_t start = info.GetAddress();
|
||||
const uintptr_t end = info.GetLastAddress();
|
||||
const size_t kb = info.GetSize() / 1_KB;
|
||||
void DumpMemoryBlock(const KMemoryBlock &block) {
|
||||
const char *state = GetMemoryStateName(block.GetState());
|
||||
const char *perm = GetMemoryPermissionString(block);
|
||||
const uintptr_t start = GetInteger(block.GetAddress());
|
||||
const uintptr_t end = GetInteger(block.GetLastAddress());
|
||||
const size_t kb = block.GetSize() / 1_KB;
|
||||
|
||||
const char l = (info.m_attribute & KMemoryAttribute_Locked) ? 'L' : '-';
|
||||
const char i = (info.m_attribute & KMemoryAttribute_IpcLocked) ? 'I' : '-';
|
||||
const char d = (info.m_attribute & KMemoryAttribute_DeviceShared) ? 'D' : '-';
|
||||
const char u = (info.m_attribute & KMemoryAttribute_Uncached) ? 'U' : '-';
|
||||
const char l = (block.GetAttribute() & KMemoryAttribute_Locked) ? 'L' : '-';
|
||||
const char i = (block.GetAttribute() & KMemoryAttribute_IpcLocked) ? 'I' : '-';
|
||||
const char d = (block.GetAttribute() & KMemoryAttribute_DeviceShared) ? 'D' : '-';
|
||||
const char u = (block.GetAttribute() & KMemoryAttribute_Uncached) ? 'U' : '-';
|
||||
|
||||
MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, info.m_ipc_lock_count, info.m_device_use_count);
|
||||
MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, block.GetIpcLockCount(), block.GetDeviceUseCount());
|
||||
}
|
||||
|
||||
}
|
||||
@ -123,15 +123,14 @@ namespace ams::kern {
|
||||
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()) {
|
||||
if (region_last < it->GetAddress()) {
|
||||
break;
|
||||
}
|
||||
if (info.m_state != KMemoryState_Free) {
|
||||
if (it->GetState() != KMemoryState_Free) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KProcessAddress area = (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress();
|
||||
KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress();
|
||||
area += guard_pages * PageSize;
|
||||
|
||||
const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset;
|
||||
@ -140,7 +139,7 @@ namespace ams::kern {
|
||||
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()) {
|
||||
if (GetInteger(it->GetAddress()) <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= GetInteger(it->GetLastAddress())) {
|
||||
return area;
|
||||
}
|
||||
}
|
||||
@ -171,7 +170,7 @@ namespace ams::kern {
|
||||
it = prev;
|
||||
}
|
||||
|
||||
if (address + num_pages * PageSize < it->GetMemoryInfo().GetEndAddress()) {
|
||||
if (address + num_pages * PageSize < it->GetEndAddress()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -189,43 +188,39 @@ namespace ams::kern {
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
if (it->HasProperties(state, perm, attr)) {
|
||||
/* If we already have the right properties, just advance. */
|
||||
if (cur_address + remaining_size < cur_info.GetEndAddress()) {
|
||||
if (cur_address + remaining_size < it->GetEndAddress()) {
|
||||
remaining_pages = 0;
|
||||
cur_address += remaining_size;
|
||||
} else {
|
||||
remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize;
|
||||
cur_address = cur_info.GetEndAddress();
|
||||
remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize;
|
||||
cur_address = it->GetEndAddress();
|
||||
}
|
||||
} else {
|
||||
/* If we need to, create a new block before and insert it. */
|
||||
if (cur_info.GetAddress() != GetInteger(cur_address)) {
|
||||
if (it->GetAddress() != GetInteger(cur_address)) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
it++;
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
cur_address = cur_info.GetAddress();
|
||||
cur_address = it->GetAddress();
|
||||
}
|
||||
|
||||
/* If we need to, create a new block after and insert it. */
|
||||
if (cur_info.GetSize() > remaining_size) {
|
||||
if (it->GetSize() > remaining_size) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address + remaining_size);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
}
|
||||
|
||||
/* Update block state. */
|
||||
it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr);
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
cur_address += it->GetSize();
|
||||
remaining_pages -= it->GetNumPages();
|
||||
}
|
||||
it++;
|
||||
}
|
||||
@ -245,42 +240,38 @@ namespace ams::kern {
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
if (it->HasProperties(test_state, test_perm, test_attr) && !it->HasProperties(state, perm, attr)) {
|
||||
/* If we need to, create a new block before and insert it. */
|
||||
if (cur_info.GetAddress() != GetInteger(cur_address)) {
|
||||
if (it->GetAddress() != GetInteger(cur_address)) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
it++;
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
cur_address = cur_info.GetAddress();
|
||||
cur_address = it->GetAddress();
|
||||
}
|
||||
|
||||
/* If we need to, create a new block after and insert it. */
|
||||
if (cur_info.GetSize() > remaining_size) {
|
||||
if (it->GetSize() > remaining_size) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address + remaining_size);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
}
|
||||
|
||||
/* Update block state. */
|
||||
it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr);
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
cur_address += it->GetSize();
|
||||
remaining_pages -= it->GetNumPages();
|
||||
} else {
|
||||
/* If we already have the right properties, just advance. */
|
||||
if (cur_address + remaining_size < cur_info.GetEndAddress()) {
|
||||
if (cur_address + remaining_size < it->GetEndAddress()) {
|
||||
remaining_pages = 0;
|
||||
cur_address += remaining_size;
|
||||
} else {
|
||||
remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize;
|
||||
cur_address = cur_info.GetEndAddress();
|
||||
remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize;
|
||||
cur_address = it->GetEndAddress();
|
||||
}
|
||||
}
|
||||
it++;
|
||||
@ -302,34 +293,30 @@ namespace ams::kern {
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
|
||||
/* If we need to, create a new block before and insert it. */
|
||||
if (cur_info.m_address != GetInteger(cur_address)) {
|
||||
if (it->GetAddress() != cur_address) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
it++;
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
cur_address = cur_info.GetAddress();
|
||||
cur_address = it->GetAddress();
|
||||
}
|
||||
|
||||
if (cur_info.GetSize() > remaining_size) {
|
||||
if (it->GetSize() > remaining_size) {
|
||||
/* If we need to, create a new block after and insert it. */
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address + remaining_size);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
}
|
||||
|
||||
/* Call the locked update function. */
|
||||
(std::addressof(*it)->*lock_func)(perm, cur_info.GetAddress() == address, cur_info.GetEndAddress() == end_address);
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
(std::addressof(*it)->*lock_func)(perm, it->GetAddress() == address, it->GetEndAddress() == end_address);
|
||||
cur_address += it->GetSize();
|
||||
remaining_pages -= it->GetNumPages();
|
||||
it++;
|
||||
}
|
||||
|
||||
@ -347,43 +334,39 @@ namespace ams::kern {
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
|
||||
if ((it->GetAttribute() & mask) != attr) {
|
||||
/* If we need to, create a new block before and insert it. */
|
||||
if (cur_info.GetAddress() != GetInteger(cur_address)) {
|
||||
if (it->GetAddress() != GetInteger(cur_address)) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
it++;
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
cur_address = cur_info.GetAddress();
|
||||
cur_address = it->GetAddress();
|
||||
}
|
||||
|
||||
/* If we need to, create a new block after and insert it. */
|
||||
if (cur_info.GetSize() > remaining_size) {
|
||||
if (it->GetSize() > remaining_size) {
|
||||
KMemoryBlock *new_block = allocator->Allocate();
|
||||
|
||||
it->Split(new_block, cur_address + remaining_size);
|
||||
it = m_memory_block_tree.insert(*new_block);
|
||||
|
||||
cur_info = it->GetMemoryInfo();
|
||||
}
|
||||
|
||||
/* Update block state. */
|
||||
it->UpdateAttribute(mask, attr);
|
||||
cur_address += cur_info.GetSize();
|
||||
remaining_pages -= cur_info.GetNumPages();
|
||||
cur_address += it->GetSize();
|
||||
remaining_pages -= it->GetNumPages();
|
||||
} else {
|
||||
/* If we already have the right attributes, just advance. */
|
||||
if (cur_address + remaining_size < cur_info.GetEndAddress()) {
|
||||
if (cur_address + remaining_size < it->GetEndAddress()) {
|
||||
remaining_pages = 0;
|
||||
cur_address += remaining_size;
|
||||
} else {
|
||||
remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize;
|
||||
cur_address = cur_info.GetEndAddress();
|
||||
remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize;
|
||||
cur_address = it->GetEndAddress();
|
||||
}
|
||||
}
|
||||
it++;
|
||||
@ -401,8 +384,6 @@ namespace ams::kern {
|
||||
auto it = m_memory_block_tree.cbegin();
|
||||
auto prev = it++;
|
||||
while (it != m_memory_block_tree.cend()) {
|
||||
const KMemoryInfo prev_info = prev->GetMemoryInfo();
|
||||
const KMemoryInfo cur_info = it->GetMemoryInfo();
|
||||
|
||||
/* Sequential blocks which can be merged should be merged. */
|
||||
if (prev->CanMergeWith(*it)) {
|
||||
@ -410,17 +391,17 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* Sequential blocks should be sequential. */
|
||||
if (prev_info.GetEndAddress() != cur_info.GetAddress()) {
|
||||
if (prev->GetEndAddress() != it->GetAddress()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the block is ipc locked, it must have a count. */
|
||||
if ((cur_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && cur_info.m_ipc_lock_count == 0) {
|
||||
if ((it->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && it->GetIpcLockCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the block is device shared, it must have a count. */
|
||||
if ((cur_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && cur_info.m_device_use_count == 0) {
|
||||
if ((it->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && it->GetDeviceUseCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -430,14 +411,13 @@ namespace ams::kern {
|
||||
|
||||
/* Our loop will miss checking the last block, potentially, so check it. */
|
||||
if (prev != m_memory_block_tree.cend()) {
|
||||
const KMemoryInfo prev_info = prev->GetMemoryInfo();
|
||||
/* If the block is ipc locked, it must have a count. */
|
||||
if ((prev_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && prev_info.m_ipc_lock_count == 0) {
|
||||
if ((prev->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && prev->GetIpcLockCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the block is device shared, it must have a count. */
|
||||
if ((prev_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && prev_info.m_device_use_count == 0) {
|
||||
if ((prev->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && prev->GetDeviceUseCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -450,7 +430,7 @@ namespace ams::kern {
|
||||
void KMemoryBlockManager::DumpBlocks() const {
|
||||
/* Dump each block. */
|
||||
for (const auto &block : m_memory_block_tree) {
|
||||
DumpMemoryInfo(block.GetMemoryInfo());
|
||||
DumpMemoryBlock(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace ams::kern {
|
||||
|
||||
}
|
||||
|
||||
void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) {
|
||||
void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts) {
|
||||
/* Clear the management region to zero. */
|
||||
const KVirtualAddress management_region_end = management_region + management_region_size;
|
||||
std::memset(GetVoidPointer(management_region), 0, management_region_size);
|
||||
@ -154,6 +154,17 @@ namespace ams::kern {
|
||||
for (size_t i = 0; i < m_num_managers; ++i) {
|
||||
m_managers[i].SetInitialUsedHeapSize(reserved_sizes[i]);
|
||||
}
|
||||
|
||||
/* Determine the min heap size for all pools. */
|
||||
for (size_t i = 0; i < Pool_Count; ++i) {
|
||||
/* Determine the min alignment for the pool in pages. */
|
||||
const size_t min_align_pages = 1 << min_align_shifts[i];
|
||||
|
||||
/* Determine a heap index. */
|
||||
if (const auto heap_index = KPageHeap::GetAlignedBlockIndex(min_align_pages, min_align_pages); heap_index >= 0) {
|
||||
m_min_heap_indexes[i] = heap_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result KMemoryManager::InitializeOptimizedMemory(u64 process_id, Pool pool) {
|
||||
@ -192,8 +203,19 @@ namespace ams::kern {
|
||||
return Null<KPhysicalAddress>;
|
||||
}
|
||||
|
||||
/* Lock the pool that we're allocating from. */
|
||||
/* Determine the pool and direction we're allocating from. */
|
||||
const auto [pool, dir] = DecodeOption(option);
|
||||
|
||||
/* Check that we're allocating a correctly aligned number of pages. */
|
||||
const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]);
|
||||
if (!util::IsAligned(num_pages, min_align_pages)) {
|
||||
return Null<KPhysicalAddress>;
|
||||
}
|
||||
|
||||
/* Update our alignment. */
|
||||
align_pages = std::max(align_pages, min_align_pages);
|
||||
|
||||
/* Lock the pool that we're allocating from. */
|
||||
KScopedLightLock lk(m_pool_locks[pool]);
|
||||
|
||||
/* Choose a heap based on our page size request. */
|
||||
@ -225,7 +247,14 @@ namespace ams::kern {
|
||||
return allocated_block;
|
||||
}
|
||||
|
||||
Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random) {
|
||||
Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index) {
|
||||
/* Check that we're allocating a correctly aligned number of pages. */
|
||||
const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]);
|
||||
R_UNLESS(util::IsAligned(num_pages, min_align_pages), svc::ResultInvalidSize());
|
||||
|
||||
/* Adjust our min heap index to the pool minimum if needed. */
|
||||
min_heap_index = std::max(min_heap_index, m_min_heap_indexes[pool]);
|
||||
|
||||
/* Choose a heap based on our page size request. */
|
||||
const s32 heap_index = KPageHeap::GetBlockIndex(num_pages);
|
||||
R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory());
|
||||
@ -241,7 +270,7 @@ namespace ams::kern {
|
||||
};
|
||||
|
||||
/* Keep allocating until we've allocated all our pages. */
|
||||
for (s32 index = heap_index; index >= 0 && num_pages > 0; index--) {
|
||||
for (s32 index = heap_index; index >= min_heap_index && 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) {
|
||||
@ -274,7 +303,7 @@ namespace ams::kern {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option) {
|
||||
Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_pages, u32 option) {
|
||||
MESOSPHERE_ASSERT(out != nullptr);
|
||||
MESOSPHERE_ASSERT(out->GetNumPages() == 0);
|
||||
|
||||
@ -285,8 +314,11 @@ 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));
|
||||
R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, m_has_optimized_process[pool], true, heap_index));
|
||||
|
||||
/* Open the first reference to the pages. */
|
||||
for (const auto &block : *out) {
|
||||
@ -326,8 +358,11 @@ 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));
|
||||
R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, false, heap_index));
|
||||
|
||||
/* Set whether we should optimize. */
|
||||
optimized = has_optimized && is_optimized;
|
||||
|
@ -84,6 +84,58 @@ 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<KPhysicalAddress>;
|
||||
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<size_t>(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();
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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,18 +220,8 @@ namespace ams::kern {
|
||||
m_running_thread_switch_counts[i] = 0;
|
||||
}
|
||||
|
||||
/* Set max memory based on address space type. */
|
||||
switch ((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask)) {
|
||||
case ams::svc::CreateProcessFlag_AddressSpace32Bit:
|
||||
case ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated:
|
||||
case ams::svc::CreateProcessFlag_AddressSpace64Bit:
|
||||
m_max_process_memory = m_page_table.GetHeapRegionSize();
|
||||
break;
|
||||
case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias:
|
||||
m_max_process_memory = m_page_table.GetHeapRegionSize() + m_page_table.GetAliasRegionSize();
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
/* Set max memory. */
|
||||
m_max_process_memory = m_page_table.GetHeapRegionSize();
|
||||
|
||||
/* Generate random entropy. */
|
||||
KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy));
|
||||
@ -298,10 +288,8 @@ namespace ams::kern {
|
||||
|
||||
/* Setup page table. */
|
||||
{
|
||||
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(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(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit));
|
||||
const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0;
|
||||
R_TRY(m_page_table.Initialize(static_cast<ams::svc::CreateProcessFlag>(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetSlabIndex()));
|
||||
}
|
||||
ON_RESULT_FAILURE_2 { m_page_table.Finalize(); };
|
||||
|
||||
@ -379,10 +367,8 @@ namespace ams::kern {
|
||||
|
||||
/* Setup page table. */
|
||||
{
|
||||
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(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(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, code_size, m_system_resource, res_limit));
|
||||
const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0;
|
||||
R_TRY(m_page_table.Initialize(static_cast<ams::svc::CreateProcessFlag>(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit, this->GetSlabIndex()));
|
||||
}
|
||||
ON_RESULT_FAILURE_2 { m_page_table.Finalize(); };
|
||||
|
||||
@ -467,7 +453,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);
|
||||
@ -938,7 +924,6 @@ namespace ams::kern {
|
||||
MESOSPHERE_ABORT_UNLESS(m_main_thread_stack_size == 0);
|
||||
|
||||
/* Ensure that we're allocating a valid stack. */
|
||||
stack_size = util::AlignUp(stack_size, PageSize);
|
||||
R_UNLESS(stack_size + m_code_size <= m_max_process_memory, svc::ResultOutOfMemory());
|
||||
R_UNLESS(stack_size + m_code_size >= m_code_size, svc::ResultOutOfMemory());
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<KMemoryPermission>(src_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelRead : KMemoryPermission_UserRead);
|
||||
const KMemoryPermission src_perm = static_cast<KMemoryPermission>(src_user ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelRead) : KMemoryPermission_UserRead);
|
||||
|
||||
/* Perform the fast part of the copy. */
|
||||
R_TRY(src_page_table.CopyMemoryFromLinearToKernel(reinterpret_cast<uintptr_t>(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<KMemoryPermission>(dst_heap ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite);
|
||||
const KMemoryPermission dst_perm = static_cast<KMemoryPermission>(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<KMemoryPermission>(dst_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite);
|
||||
const KMemoryPermission dst_perm = static_cast<KMemoryPermission>(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,
|
||||
|
@ -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, owner->GetAllocateOption()));
|
||||
R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(m_page_group), num_pages, 1, owner->GetAllocateOption()));
|
||||
|
||||
/* Commit our reservation. */
|
||||
memory_reservation.Commit();
|
||||
|
@ -39,17 +39,18 @@ 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) {
|
||||
void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address) {
|
||||
*out = {
|
||||
.address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax,
|
||||
._08 = 0,
|
||||
.address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax,
|
||||
._08 = 0,
|
||||
.kern_address = GetInteger(kern_base_address),
|
||||
};
|
||||
}
|
||||
|
||||
@ -77,7 +78,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, false>(core_id, entrypoint, arg)) == 0);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0>(core_id, entrypoint, arg)) == 0);
|
||||
#else
|
||||
AMS_INFINITE_LOOP();
|
||||
#endif
|
||||
@ -123,31 +124,14 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* System Initialization. */
|
||||
void KSystemControlBase::ConfigureKTargetSystem() {
|
||||
/* By default, use the default config set in the KTargetSystem header. */
|
||||
}
|
||||
|
||||
void KSystemControlBase::InitializePhase1() {
|
||||
/* Configure KTargetSystem. */
|
||||
/* Enable KTargetSystem. */
|
||||
{
|
||||
/* Set IsDebugMode. */
|
||||
{
|
||||
KTargetSystem::SetIsDebugMode(true);
|
||||
|
||||
/* If debug mode, we want to initialize uart logging. */
|
||||
KTargetSystem::EnableDebugLogging(true);
|
||||
}
|
||||
|
||||
/* Set Kernel Configuration. */
|
||||
{
|
||||
KTargetSystem::EnableDebugMemoryFill(false);
|
||||
KTargetSystem::EnableUserExceptionHandlers(true);
|
||||
KTargetSystem::EnableDynamicResourceLimits(true);
|
||||
KTargetSystem::EnableUserPmuAccess(false);
|
||||
}
|
||||
|
||||
/* Set Kernel Debugging. */
|
||||
{
|
||||
/* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */
|
||||
/* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */
|
||||
KTargetSystem::EnableKernelDebugging(true);
|
||||
}
|
||||
KTargetSystem::SetInitialized();
|
||||
}
|
||||
|
||||
/* Initialize random and resource limit. */
|
||||
|
@ -1438,7 +1438,10 @@ namespace ams::kern {
|
||||
this->SetState(ThreadState_Waiting);
|
||||
|
||||
/* Set our wait queue. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdangling-pointer"
|
||||
m_wait_queue = queue;
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
void KThread::NotifyAvailable(KSynchronizationObject *signaled_object, Result wait_result) {
|
||||
|
@ -56,8 +56,9 @@ namespace ams::kern {
|
||||
{
|
||||
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
|
||||
MESOSPHERE_ABORT_UNLESS(management_region.GetEndAddress() != 0);
|
||||
static_assert(util::size(MinimumMemoryManagerAlignmentShifts) == KMemoryManager::Pool_Count);
|
||||
|
||||
Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize());
|
||||
Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize(), MinimumMemoryManagerAlignmentShifts);
|
||||
}
|
||||
|
||||
/* Copy the Initial Process Binary to safe memory. */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user