Secure Monitor: Difference between revisions

No edit summary
 
(94 intermediate revisions by 9 users not shown)
Line 1: Line 1:
= Secure Monitor Calls =
= SMC =
 
The secure monitor provides two top level handlers of which each provides a range of sub handlers.
The secure monitor provides two top level handlers of which each provides a range of sub handlers.


Secure Monitor Calls follow the ARM SMC calling convention up to a small change:
Secure Monitor calls follow the ARM SMC calling convention with a small change:
{| class=wikitable
{| class=wikitable
! Bit number || Bit mask || Description
! Bits || Description
|-
|-
| 31 || 0x80000000 || Set to 0 means Yielding Call; Set to 1 means Fast Call.
| 0-7 || Function Number
|-
|-
| 30 || 0x40000000 || Set to 0 means SMC32 convention; Set to 1 means SMC64.
| 8-15 || Argument Type
|-
|-
| 29-24 || 0x3F000000 || Service Call ranges.
| 16-23 || Reserved
|-
|-
| 23-16 || 0x00FF0000 || Must be zero.
| 24-29 || Call Range
|-
|-
| 15-8 || 0x0000FF00 || Argument type. This is different from the ARM SMC calling convention.
| 30 || Call Convention (0 = SMC32, 1 = SMC64)
|-
|-
| 7-0 || 0x000000FF || Function number within the range call type.
| 31 || Call Type (0 = Yielding Call, 1 = Fast Call)
|}
|}


If bit ''n'' is set in the argument type then parameter X''n'' is treated as a pointer and the kernel will setup address translation for it in [[SVC#svcCallSecureMonitor|svcCallSecureMonitor]].
If bit ''n'' is set in the argument type then parameter X''n'' is treated as a pointer and the kernel will setup address translation for it in [[SVC#svcCallSecureMonitor|svcCallSecureMonitor]].


== Id 0 ==
SMC arguments are passed using registers X0-X7 with X0 always sending the call sub-id and returning the result of the call.
Functions exposed to user-mode processes using [[SVC|svcCallSecureMonitor]].
 
== FunctionId0 ==
Functions exposed to user-mode processes using [[SVC|svcCallSecureMonitor]]. SMCs should be called from CPUID 3 (where SPL runs).


{| class=wikitable
{| class=wikitable
! Sub-Id || Name || In || Out
! Value || Name
|-
|-
| 0xC3000401 || SetConfig || ||
| 0xC3000401 || SetConfig
|-
|-
| 0xC3000002 || GetConfig (Same as Id 1 Sub-Id 4.) || ||
| 0xC3000002 || [[#GetConfig|GetConfig]] (same as in [[#FunctionId1]])
|-
|-
| 0xC3000003 || CheckStatus_5_9_F_10 || ||
| 0xC3000003 || GetResult
|-
|-
| 0xC3000404 || GetResult_5_9_F_10 || ||
| 0xC3000404 || GetResultData
|-
|-
| 0xC3000E05 || ExpMod || ||
| 0xC3000E05 || ModularExponentiate
|-
|-
| 0xC3000006 || PrngX931 (Same as Id 1 Sub-Id 5.) || ||
| 0xC3000006 || [[#GenerateRandomBytes|GenerateRandomBytes]] (same as in [[#FunctionId1]])
|-
|-
| 0xC3000007 || KeygenAndSealX || ||
| 0xC3000007 || [[#GenerateAesKek|GenerateAesKek]]
|-
|-
| 0xC3000008 || SetKeyslotFromXY || ||
| 0xC3000008 || [[#LoadAesKey|LoadAesKey]]
|-
|-
| 0xC3000009 || SymmetricCrypto || ||
| 0xC3000009 || [[#ComputeAes|ComputeAes]]
|-
|-
| 0xC300000A || KeygenA || ||
| 0xC300000A || [[#GenerateSpecificAesKey|GenerateSpecificAesKey]]
|-
|-
| 0xC300040B || CMAC || ||
| 0xC300040B || [[#ComputeCmac|ComputeCmac]]
|-
|-
| 0xC300100C || ImportParamsFor10WithXY || ||
| [1.0.0-4.1.0] 0xC300100C || [[#DecryptAndImportEsDeviceKey|DecryptAndImportEsDeviceKey]]
|-
|-
| 0xC300100D || DecryptExpModParamsWithXY || ||
| [5.0.0+] 0xC300D60C || [[#ReencryptDeviceUniqueData|ReencryptDeviceUniqueData]]
|-
|-
| 0xC300100E || ImportParamsForFWithXY || ||
| 0xC300100D || [[#DecryptDeviceUniqueData|DecryptDeviceUniqueData]]
|-
|-
| 0xC300060F || ExpMod || ||
| [1.0.0-4.1.0] 0xC300100E || [[#DecryptAndImportLotusKey|DecryptAndImportLotusKey]]
|-
|-
| 0xC3000610 || ExpModAndKeygenAndSealZ || ||
| 0xC300060F || [[#ModularExponentiateByStorageKey|ModularExponentiateByStorageKey]]
|-
|-
| 0xC3000011 || SetKeyslotFromZ || ||
| 0xC3000610 || [[#PrepareEsDeviceUniqueKey|PrepareEsDeviceUniqueKey]]
|-
|-
| 0xC3000012 || [2.0.0+] KeygenAndSealZ || ||
| 0xC3000011 || [[#LoadPreparedAesKey|LoadPreparedAesKey]]
|-
| 0xC3000012 || [2.0.0+] [[#PrepareEsCommonKey|PrepareEsCommonKey]]
|}
|}


== Id 1 ==
The overall concept here is the following:
* All key material (AES and RSA) is stored in userspace, but it's encrypted with random AES kek's ("key encryption keys").
* Each kek is generated as a function of an access key (picked at random).
* The kek is generated differently depending on the [[#CryptoUsecase]] the key is used for.
** This means: Each key is "locked" to the [[#CryptoUsecase]] it was designated for.
** You can use a key for a different usecase, but you will only get garbage output.
* After the kek has been generated, it is wrapped with a session-specific key and given back to userspace.
** This means: Plaintext kek keys never leave TrustZone.
** Further, this means: Actual AES/RSA keys never leave TrustZone.
 
=== GenerateRandomBytes ===
Takes an u64 '''Size'''. Returns [[#Result]] and '''RandomBytes'''.
 
'''Size''' is limited to 0x38 (for fitting in return registers).
 
=== GenerateAesKek ===
Takes an "access key" as input, an [[#CryptoUsecase]].
 
Returns a session-unique kek for said usecase.
 
=== LoadAesKey ===
Takes a session kek created with [[#GenerateAesKek]], and a wrapped AES key.
 
The session kek must have been created with [[#CryptoUsecase|CryptoUsecase Aes]].
 
=== ComputeAes ===
Encrypts/decrypts using AES (CTR and CBC). Takes an [[#CipherMode]].
 
Key must be set prior using one of the [[#LoadAesKey]] or [[#GenerateSpecificAesKey]] commands.
 
=== GenerateSpecificAesKey ===
Takes a wrapped AES key and decrypts it using static data.
 
=== ComputeCmac ===
Calculates CMAC over input data.
 
=== DecryptAndImportEsDeviceKey ===
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, and a wrapped RSA private key.
 
The session kek must have been created with [[#CryptoUsecase|CryptoUsecase TitleKey]].
 
[5.0.0] This function was removed and replaced with [[#ReencryptDeviceUniqueData]].
 
=== ReencryptDeviceUniqueData ===
Takes in two session keks created with [[#GenerateAesKek]], two wrapped AES keys, an enum member, and a wrapped RSA private key.
 
Decrypts and validates the wrapped RSA private key with the first kek/wrapped key, and re-encrypts it with the second if valid.
 
The re-encrypted key is then passed to the user, for use with [[#DecryptDeviceUniqueData]].
 
=== DecryptDeviceUniqueData ===
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, an enum member, and a wrapped RSA private key.
 
The session kek must have been created with [[#CryptoUsecase|CryptoUsecase RsaPrivate]].
 
[4.0.0+] The SMC handler when certain conditions pass and FunctionId0==0xC300100D now returns error 0x6 instead of calling the handler funcptr.
 
[5.0.0+] This function now takes an additional input [[#DecryptOrImportMode]]. This extends the original functionality to enable importing private keys into the security engine instead of decrypting them.
 
=== DecryptAndImportLotusKey ===
Takes a session kek created with [[#GenerateAesKek]], and a wrapped RSA key.
 
The session kek must have been created with [[#CryptoUsecase|CryptoUsecase RsaSecureExpMod]].
 
[5.0.0] This function was removed.
 
=== ModularExponentiateByStorageKey ===
Performs an ExpMod operation using an exponent previously loaded with the [[#DecryptAndImportLotusKey]] command.
 
[5.0.0+] This now uses any exponent previously loaded with [[#DecryptDeviceUniqueData]] and takes an [[#SecureExpModMode]].
 
=== PrepareEsDeviceUniqueKey ===
Takes an Rsa-Oaep-wrapped TitleKey, an RSA Public Key, and a label hash.
 
Performs an ExpMod operation using an exponent previously loaded with the [[#DecryptAndImportEsDeviceKey]] command, and then validates/extracts a Titlekey from the resulting message.
 
Returns a session-unique AES key especially for use in [[#LoadTitleKey]].
 
[5.0.0+] This now uses any exponent previously loaded with [[#DecryptDeviceUniqueData]].
 
=== LoadPreparedAesKey ===
Takes a session-unique AES key from [[#PrepareEsCommonKey]] or [[#PrepareEsDeviceUniqueKey]].
 
=== PrepareEsCommonKey ===
Takes an AES-wrapped common TitleKey and returns a sealed AES key.
 
== FunctionId1 ==
Functions exposed to the kernel internally.
Functions exposed to the kernel internally.


{| class=wikitable
{| class=wikitable
! Sub-Id || Name || In || Out
! Value || Name
|-
| 0xC4000001 || [[#SuspendCpu|SuspendCpu]]
|-
| 0x84000002 || [[#PowerOffCpu|PowerOffCpu]]
|-
| 0xC4000003 || [[#PowerOnCpu|PowerOnCpu]]
|-
| 0xC3000004 || [[#GetConfig|GetConfig]] (same as in [[#FunctionId0]])
|-
| 0xC3000005 || [[#GenerateRandomBytes|GenerateRandomBytesNonBlocking]]
|-
| 0xC3000006 || [[#ShowError|ShowError]]
|-
| 0xC3000007 || [2.0.0+] [[#SetKernelCarveoutRegion|SetKernelCarveoutRegion]]
|-
| 0xC3000008 || [2.0.0+] [[#ReadWriteRegister|ReadWriteRegister]]
|}
 
=== SuspendCpu ===
Takes an u64 '''PowerState''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. No output.
 
Suspends the CPU (CPU0).
 
The kernel calls this SMC on shutdown with '''PowerState''' set to 0x0201001B (power level: 0x02==system; power type: 0x01==powerdown; ID: 0x1B).
 
=== PowerOffCpu ===
No input/output.
 
Turns off the CPU (CPU1, CPU2 or CPU3).
 
=== PowerOnCpu ===
Takes an u64 '''TargetCpu''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. Returns [[#Result]].
 
Turns on the CPU (CPU1, CPU2 or CPU3).
 
=== GetConfig ===
Takes a [[#ConfigItem]]. Returns [[#Result]] and a '''ConfigValue'''.
 
==== ConfigItem ====
{| class="wikitable" border="1"
|-
! Value || Name
|-
| 1 || [[#DisableProgramVerification]]
|-
| 2 || [[#DramId]]
|-
| 3 || [[#SecurityEngineInterruptNumber]]
|-
| 4 || [[#FuseVersion]]
|-
| 5 || [[#HardwareType]]
|-
| 6 || [[#HardwareState]]
|-
| 7 || [[#IsRecoveryBoot]]
|-
| 8 || [[#DeviceId]]
|-
| 9 || [1.0.0-4.0.0] [[#BootReason]]
|-
| 10 || [[#MemoryMode]]
|-
| 11 || [[#IsDevelopmentFunctionEnabled]]
|-
| 12 || [[#KernelConfiguration]]
|-
| 13 || [[#IsChargerHiZModeEnabled]]
|-
| 14 || [4.0.0+] [[#RetailInteractiveDisplayState]]
|-
| 15 || [5.0.0+] [[#RegulatorType]]
|-
| 16 || [5.0.0+] [[#DeviceUniqueKeyGeneration]]
|-
| 17 || [5.0.0+] [[#Package2Hash]]
|}
 
===== DisableProgramVerification =====
[[Process Manager services|PM]] checks this item and if non-zero, calls fsp-pr SetEnabledProgramVerification(false).
 
===== DramId =====
{| class="wikitable" border="1"
|-
! Value
! Description
|-
| 0
| EristaIcosaSamsung4gb
|-
| 1
| EristaIcosaHynix4gb
|-
| 2
| EristaIcosaMicron4gb
|-
| 3
| [11.0.0+] MarikoIowaHynix1y4gb ([1.0.0-10.2.0] EristaCopperSamsung4gb)
|-
| 4
| EristaIcosaSamsung6gb
|-
| 5
| [12.0.0+] MarikoHoagHynix1y4gb ([4.0.0-11.0.1] EristaCopperHynix4gb)
|-
| 6
| [13.0.0+] MarikoAulaHynix1y4gb ([4.0.0-12.1.0] EristaCopperMicron4gb)
|-
| 7
| [15.0.0+] Reserved ([5.0.0-14.1.2] MarikoIowax1x2Samsung4gb, [4.0.0-4.1.0] Reserved)
|-
| 8
| [5.0.0+] MarikoIowaSamsung4gb
|-
| 9
| [5.0.0+] MarikoIowaSamsung8gb
|-
| 10
| [6.0.0+] MarikoIowaHynix4gb ([5.0.0-5.1.0] Reserved)
|-
| 11
| [7.0.0+] MarikoIowaMicron4gb ([5.0.0-6.2.0] Reserved)
|-
| 12
| [5.0.0+] MarikoHoagSamsung4gb
|-
| 13
| [5.0.0+] MarikoHoagSamsung8gb
|-
| 14
| [7.0.0+] MarikoHoagHynix4gb ([5.0.0-6.2.0] Reserved)
|-
| 15
| [7.0.0+] MarikoHoagMicron4gb ([5.0.0-6.2.0] Reserved)
|-
| 16
| [15.0.0+] Reserved ([8.0.0-14.1.2] MarikoIowaSamsung4gbY)
|-
| 17
| [9.0.0+] MarikoIowaSamsung1y4gbX
|-
| 18
| [9.0.0+] MarikoIowaSamsung1y8gbX
|-
| 19
| [9.0.0+] MarikoHoagSamsung1y4gbX
|-
| 20
| [14.0.0+] MarikoIowaSamsung1z4gb ([9.0.0-13.2.1] MarikoIowaSamsung1y4gbY)
|-
| 21
| [14.0.0+] MarikoHoagSamsung1z4gb ([9.0.0-13.2.1] MarikoIowaSamsung1y8gbY)
|-
| 22
| [14.0.0+] MarikoAulaSamsung1z4gb ([13.0.0-13.2.1] Reserved, [9.0.0-12.1.0] MarikoAulaSamsung1y4gb)
|-
| 23
| [10.0.0+] MarikoHoagSamsung1y8gbX
|-
| 24
| [10.0.0+] MarikoAulaSamsung1y4gbX
|-
| 25
| [11.0.0+] MarikoIowaMicron1y4gb
|-
| 26
| [11.0.0+] MarikoHoagMicron1y4gb
|-
| 27
| [11.0.0+] MarikoAulaMicron1y4gb
|-
| 28
| [11.0.0+] MarikoAulaSamsung1y8gbX
|-
| 29
| [16.0.0+] MarikoIowaHynix1a4gb ([15.0.0-15.0.1] MarikoIowax1x2Samsung4gb)
|-
| 30
| [16.0.0+] MarikoHoagHynix1a4gb ([15.0.0-15.0.1] MarikoHoagx1x2Samsung4gb)
|-
| 31
| [16.0.0+] MarikoAulaHynix1a4gb ([15.0.0-15.0.1] MarikoAulax1x2Samsung4gb)
|-
| 32
| [16.0.0+] MarikoIowaMicron1a4gb ([15.0.0-15.0.1] MarikoIowaSamsung4gbY)
|-
| 33
| [16.0.0+] MarikoHoagMicron1a4gb ([15.0.0-15.0.1] MarikoHoagSamsung4gbY)
|-
| 34
| [16.0.0+] MarikoAulaMicron1a4gb ([15.0.0-15.0.1] MarikoAulaSamsung4gbY)
|}
 
This is extracted directly from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
[[PCV_services|PCV]] selects memory training tables based on DramId.
{| class="wikitable" border="1"
|-
! SocType
! Platform
! DramId
! Revision
! DVFS
|-
| Erista
| jetson-tx1
| N/A
| 0x07
|
11_40800_01_V9.8.3_V1.6
11_68000_01_V9.8.3_V1.6
11_102000_01_V9.8.3_V1.6
11_204000_05_V9.8.3_V1.6
11_408000_02_V9.8.3_V1.6
11_665600_03_V9.8.3_V1.6
11_800000_01_V9.8.3_V1.6
11_1065600_01_V9.8.3_V1.6
11_1331200_01_V9.8.3_V1.6
11_1600000_02_V9.8.3_V1.6
|-
| Erista
| nx-abcb
| EristaIcosaSamsung4gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.7_V1.6
10_68000_NoCfgVersion_V9.8.7_V1.6
10_102000_NoCfgVersion_V9.8.7_V1.6
10_204000_NoCfgVersion_V9.8.7_V1.6
10_408000_NoCfgVersion_V9.8.7_V1.6
10_665600_NoCfgVersion_V9.8.7_V1.6
10_800000_NoCfgVersion_V9.8.7_V1.6
10_1065600_NoCfgVersion_V9.8.7_V1.6
10_1331200_NoCfgVersion_V9.8.7_V1.6
10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
| Erista
| nx-abcb
| EristaIcosaMicron4gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.4_V1.6
10_68000_NoCfgVersion_V9.8.4_V1.6
10_102000_NoCfgVersion_V9.8.4_V1.6
10_204000_NoCfgVersion_V9.8.4_V1.6
10_408000_NoCfgVersion_V9.8.4_V1.6
10_665600_NoCfgVersion_V9.8.4_V1.6
10_800000_NoCfgVersion_V9.8.4_V1.6
10_1065600_NoCfgVersion_V9.8.4_V1.6
10_1331200_NoCfgVersion_V9.8.4_V1.6
10_1600000_NoCfgVersion_V9.8.4_V1.6
|-
| Erista
| nx-abcb
| EristaIcosaHynix4gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.4_V1.6
10_68000_NoCfgVersion_V9.8.4_V1.6
10_102000_NoCfgVersion_V9.8.4_V1.6
10_204000_NoCfgVersion_V9.8.4_V1.6
10_408000_NoCfgVersion_V9.8.4_V1.6
10_665600_NoCfgVersion_V9.8.4_V1.6
10_800000_NoCfgVersion_V9.8.4_V1.6
10_1065600_NoCfgVersion_V9.8.4_V1.6
10_1331200_NoCfgVersion_V9.8.4_V1.6
10_1600000_NoCfgVersion_V9.8.4_V1.6
|-
| Erista
| nx-abca2
| EristaIcosaSamsung4gb, EristaIcosaMicron4gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.7_V1.6
10_68000_NoCfgVersion_V9.8.7_V1.6
10_102000_NoCfgVersion_V9.8.7_V1.6
10_204000_NoCfgVersion_V9.8.7_V1.6
10_408000_NoCfgVersion_V9.8.7_V1.6
10_665600_NoCfgVersion_V9.8.7_V1.6
10_800000_NoCfgVersion_V9.8.7_V1.6
10_1065600_NoCfgVersion_V9.8.7_V1.6
10_1331200_NoCfgVersion_V9.8.7_V1.6
10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
| Erista
| nx-abca2
| EristaIcosaHynix4gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.7_V1.6
10_68000_NoCfgVersion_V9.8.7_V1.6
10_102000_NoCfgVersion_V9.8.7_V1.6
10_204000_NoCfgVersion_V9.8.7_V1.6
10_408000_NoCfgVersion_V9.8.7_V1.6
10_665600_NoCfgVersion_V9.8.7_V1.6
10_800000_NoCfgVersion_V9.8.7_V1.6
10_1065600_NoCfgVersion_V9.8.7_V1.6
10_1331200_NoCfgVersion_V9.8.7_V1.6
10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
| Erista
| nx-abca2
| EristaIcosaSamsung6gb
| 0x07
|
10_40800_NoCfgVersion_V9.8.7_V1.6
10_68000_NoCfgVersion_V9.8.7_V1.6
10_102000_NoCfgVersion_V9.8.7_V1.6
10_204000_NoCfgVersion_V9.8.7_V1.6
10_408000_NoCfgVersion_V9.8.7_V1.6
10_665600_NoCfgVersion_V9.8.7_V1.6
10_800000_NoCfgVersion_V9.8.7_V1.6
10_1065600_NoCfgVersion_V9.8.7_V1.6
10_1331200_NoCfgVersion_V9.8.7_V1.6
10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowax1x2Samsung4gb
| 0x03
|
01_204000_NoCfgVersion_V0.3.1_V2.0
01_1331200.0_NoCfgVersion_V0.3.1_V2.0
01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung4gb, MarikoHoagSamsung4gb
| 0x03
01_204000_NoCfgVersion_V0.3.1_V2.0
01_1331200.0_NoCfgVersion_V0.3.1_V2.0
01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung8gb, MarikoHoagSamsung8gb
| 0x03
|
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaHynix4gb, MarikoHoagHynix4gb
| 0x03
01_204000_NoCfgVersion_V0.3.1_V2.0
01_1331200.0_NoCfgVersion_V0.3.1_V2.0
01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaMicron4gb, MarikoHoagMicron4gb
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung4gbY
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbX
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y8gbX
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoHoagSamsung1y4gbX
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbY
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y8gbY
| 0x03
01_204000_NoCfgVersion_V0.4.2_V2.0
01_1331200.0_NoCfgVersion_V0.4.2_V2.0
01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbA
| 0x03
01_204000_NoCfgVersion_V0.4.5_V2.0
01_1331200.0_NoCfgVersion_V0.4.5_V2.0
01_1600000_NoCfgVersion_V0.4.5_V2.0
|}
 
'''nx-abca2''' ('''Icosa''' in '''Erista''', '''Iowa''' in '''Mariko''') hardware types are variations of the retail, EDEV and SDEV form factors.
 
'''nx-abcb''' ('''Copper''' in '''Erista''', '''Calcio''' in '''Mariko''') is unreleased. Among other differences, this has extra hardware to support HDMI output.
 
[8.0.0+] '''nx-abcc''' ('''Hoag''') was added for the Lite retail and HDEV form factors.
 
[10.0.0+] '''nx-abcd''' ('''Aula''') was added for the OLED Model retail and ADEV form factors.
 
'''Erista''' memory is LPDDR4, while '''Mariko''' memory is LPDDR4X.
 
===== SecurityEngineInterruptNumber =====
SPL uses this for setting up the security engine IRQ.
 
===== FuseVersion =====
The current [[Package2#Versions|bootloader maximum version]] - 1.
 
===== HardwareType =====
{| class=wikitable
! Value || Description
|-
| 0 || Icosa
|-
| 1 || Copper
|-
| 2 || [8.0.0+] Hoag ([1.0.0-7.0.1] Invalid)
|-
| 3 || [4.0.0+] Iowa
|-
| 4 || [8.0.0+] Calcio
|-
| 5 || [10.0.0+] Aula
|-
| 15 || Invalid
|}
 
[1.0.0+] This item is obtained by checking bits 8 and 2 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
[4.0.0+] This item is obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
[7.0.0+] This item can now only be 0 (Icosa) or 15 (Invalid) in Erista units.
 
Hardware is '''Icosa''' (Erista retail, EDEV and SDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 1 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 0.
 
Hardware is '''Copper''' (unreleased Erista model) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 1.
 
[4.0.0+] Hardware is '''Iowa''' (Mariko retail, EDEV and SDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 1.
 
[8.0.0+] Hardware is '''Hoag''' (Mariko Lite retail and HDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 2.
 
[8.0.0+] Hardware is '''Calcio''' (unreleased Mariko model) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 1.
 
[10.0.0+] Hardware is '''Aula''' (Mariko OLED Model retail and ADEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 4.
 
===== HardwareState =====
{| class=wikitable
! Value || Description
|-
| 0 || Development
|-
| 1 || Production
|-
| 2 || Invalid
|}
 
This item is obtained by checking bits 9 and 0-1 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
Hardware is '''Development''' if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState1]] (bits 0-1) is 3 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState2]] (bit 9) is 0.
 
Hardware is '''Production''' if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState1]] (bits 0-1) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState2]] (bit 9) is 1.
 
===== IsRecoveryBoot =====
Used to determine if the system is booting from SafeMode firmware.
 
Under normal circumstances, this just returns bit 0 of the active [[BCT#bootloader0_info|bootloader info]]'s attribute field.
 
===== DeviceId =====
[[NIM_services|NIM]] checks if this item matches the [[Settings_services|set:cal]] DeviceId with byte7 cleared. If they don't match, a panic is thrown.
 
===== BootReason =====
{| class=wikitable
! Value || Description
|-
| 0 || Invalid
|-
| 1 || AcOk
|-
| 2 || OnKey
|-
| 3 || RtcAlarm1
|-
| 4 || RtcAlarm2
|}
 
Used to determine how the system booted.
 
===== MemoryMode =====
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 0-3
| Purpose (0 = None, 1 = ForStandard, 2 = ForAppletDev, 3 = ForSystemDev)
|-
| 4-7
| Size (0 = 4GB, 1 = 6GB, 2 = 8GB)
|}
 
[[Process Manager services|PM]] and the kernel decide memory arrangement based on MemoryMode.
{| class="wikitable" border="1"
|-
! MemoryArrange
! MemoryMode
! Description
|-
| 0
| 0x01
| Standard
|-
| 1
| 0x02
| StandardForAppletDev
|-
| 2
| 0x03
| StandardForSystemDev
|-
| 3
| 0x11
| Expanded
|-
| 4
| 0x12
| ExpandedForAppletDev
|-
| 5
| 0x21
| ExpandedForMarikoDev
|}
 
===== IsDevelopmentFunctionEnabled =====
Kernel uses this to determine behavior of [[SVC#svcBreak|svcBreak]] positive arguments. It will break instead of just force-exiting the process which is what happens on retail.
 
[2.0.0+] This is also used with certain debug [[SVC|SVCs]].
 
[3.0.0+] [[Loader services|RO]] checks this and if set then skipping NRR rsa signatures is allowed.
 
===== KernelConfiguration =====
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 0
| EnableNonZeroFillMemory
|-
| 1
| EnableUserExceptionHandler
|-
| 2
| EnablePmuAccess
|-
| 3
| [8.0.0+] EnableExtraThreadResourceAllocation
|-
| 4
| [13.0.0+] DisableDynamicSystemResourceAllocation
|-
| 8
| CallShowErrorOnPanic
|-
| 16-17
| MemorySize
|}
 
Kernel reads this when setting up memory-related code.
 
'''EnableNonZeroFillMemory''' is a boolean determining whether kernel should it will memset various allocated memory-regions with 0x58, 0x59, 0x5A ('X', 'Y', 'Z') instead of zero. This allows Nintendo devs to find uninitialized memory bugs.
 
'''EnableUserExceptionHandler''' is a boolean determining whether kernel should forcefully enable usermode exception handlers (when false, only certain aborts (((1LL << (esr >> 26)) & 0x1115804400224001) == 0, typically data/prefetch aborts) that occur when the faulting address is in a readable region with MemoryType_CodeStatic will trigger usermode exception handlers).
 
'''EnablePmuAccess''' is a boolean determining whether kernel should enable usermode access to the Performance Monitors (whether PMUSERENR_EL0 should be 1 or 0).
 
'''EnableExtraThreadResourceAllocation''' is a boolean determining whether the kernel should increase the KThread slabheap capacity by 160. This also increases object capacities that are calculated based on number of threads.
 
'''CallShowErrorOnPanic''' is a boolean determining whether kernel should call smcPanic on error instead of infinite-looping.
 
'''MemorySize''' determines how much memory is available. 00/03 = 4 GB, 01 = 6 GB, 02 = 8 GB.
 
===== IsChargerHiZModeEnabled =====
This tells if the TI Charger (bq24192) is active.
 
===== RetailInteractiveDisplayState =====
{| class=wikitable
! Value || Description
|-
|-
| 0xC4000001 || CPU_SUSPEND (oyasumi) || ||
| 0 || Disabled
|-
| 1 || Enabled
|}
 
This item is bit 10 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
[4.0.0+] [[Settings_services|Settings]] uses this value to overwrite the quest flag from [[Settings_services#set:sys|GetQuestFlag]]. This is used to detect if a Switch is a kiosk unit for display at retail stores.
 
===== RegulatorType =====
{| class="wikitable" border="1"
|-
! Value
! SocType
! GPU
! Power Blocks
|-
| 0
| Erista
| GM20B (0x12B)
| max77620_sd0, max77621_cpu and max77621_gpu
|-
| 1
| Mariko
| GM20B_B (0x12E)
| max77620_sd0, max77812_cpu and max77812_gpu
|-
| 2
| Mariko
| GM20B_B (0x12E)
| max77620_sd0, max77812_cpu and max77812_gpu
|}
 
[5.0.0+] [[PCV_services|PCV]] uses this value in combination with [[#HardwareType|HardwareType]] to configure power blocks and memory tables for different hardware.
 
===== DeviceUniqueKeyGeneration =====
This item is obtained from [[Fuse_registers#FUSE_RESERVED_ODM2|FUSE_RESERVED_ODM2]] if bit 11 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]] is set, [[Fuse_registers#FUSE_RESERVED_ODM0|FUSE_RESERVED_ODM0]] matches 0x8E61ECAE and [[Fuse_registers#FUSE_RESERVED_ODM1|FUSE_RESERVED_ODM1]] matches 0xF2BA3BB2.
 
[5.0.0+] [[Filesystem services|FS]] can now use this value for the '''KeyGeneration''' parameter when calling [[#GenerateAesKek|GenerateAesKek]] during "GetBisEncryptionKey".
 
===== Package2Hash =====
This is a SHA-256 hash calculated over the [[Package2|package2]] image. Since the hash calculation is an optional step in pkg2ldr, this item is only valid in recovery mode. Otherwise, an error is returned instead.
 
=== ShowError ===
Takes an u32 '''Color''' and issues a system panic.
 
The kernel always calls this with '''Color''' set to 0xF00.
 
=== SetKernelCarveoutRegion ===
Takes an u64 '''Index''', an u64 '''Address''' and an u64 '''Size'''. Returns [[#Result]].
 
If '''Index''' is 0, '''Address''' and '''Size''' are used to configure '''MC_SECURITY_CARVEOUT4'''.
If '''Index''' is 1, '''Address''' and '''Size''' are used to configure '''MC_SECURITY_CARVEOUT5'''.
Any other '''Index''' values are invalid.
 
The kernel calls this with '''Index''' set to 0, '''Address''' set to 0x80060000 and '''Size''' set to a dynamically calculated size which covers all the kernel and built-in sysmodules' DRAM regions.
 
=== ReadWriteRegister ===
Takes an u64 '''Register''', an u32 '''Mask''' and an u32 '''InValue'''. Returns [[#Result]] and an u32 '''OutValue'''.
 
Relays [[SVC#svcReadWriteRegister|svcReadWriteRegister]] to the Secure Monitor.
 
= CryptoUsecase =
{| class=wikitable
! Value || Name
|-
| 0 || Aes
|-
| 1 || RsaPrivate
|-
| 2 || SecureExpMod
|-
| 3 || RsaOaep
|-
| 4 || [5.0.0+] RsaImport
|-
| 5 || [5.0.0+]
|-
| 6 || [5.0.0+]
|}
 
= CipherMode =
{| class=wikitable
! Value || Name
|-
| 0 || CbcEncrypt
|-
| 1 || CbcDecrypt
|-
| 2 || Ctr
|}
 
= DecryptOrImportMode =
{| class=wikitable
! Value || Name
|-
| 0 || DecryptRsaPrivateKey
|-
| 1 || ImportLotusKey
|-
| 2 || ImportEsKey
|-
| 3 || ImportSslKey
|-
| 4 || ImportDrmKey
|}
 
= SecureExpModMode =
{| class=wikitable
! Value || Name
|-
| 0 || Lotus
|-
| 1 || Ssl
|-
| 2 || Drm
|}
 
= EsKeyType =
{| class=wikitable
! Value || Name
|-
| 0 || TitleKey
|-
| 1 || ElicenseKey
|}
 
= Result =
{| class=wikitable
! Value || Description
|-
|-
| 0x84000002 || CPU_OFF || ||
| 0 || Success
|-
|-
| 0xC4000003 || CPU_ON || ||
| 1 || Not implemented
|-
|-
| 0xC3000004 || GetConfig (Same as Id 0 Sub-Id 2.) || ||
| 2 || Invalid argument
|-
|-
| 0xC3000005 || PrngX931 (Same as Id 0 Sub-Id 6.) || ||
| 3 || In progress
|-
|-
| 0xC3000006 || Panic || ||
| 4 || No async operation
|-
|-
| 0xC3000007 || || ||
| 5 || Invalid async operation
|-
|-
| 0xC3000008 || ReadWriteRegister || ||
| 6 || [8.0.0+] Not permitted
|}
|}