Changes

16,237 bytes added ,  16:33, 11 June 2020
Line 27: Line 27:     
== ASLR Implementation ==
 
== ASLR Implementation ==
The kernel uses a MT19937 random number generator, seeded by a [[SMC#GetRandomBytes|smcGetRandomBytes]]
+
The kernel uses a MT19937 random number generator, seeded by [[SMC#GetRandomBytes|smcGetRandomBytes]].
 +
 
 
=== 1.0.0 ===
 
=== 1.0.0 ===
   Line 68: Line 69:  
KASLR is being used since [[5.0.0]], but not before, with the following pseudocode (might contains some errors):
 
KASLR is being used since [[5.0.0]], but not before, with the following pseudocode (might contains some errors):
   −
<code><pre>
+
<pre>
 
DRAM crt0 mapping (ttbr1): offsets DRAM with (rand64ViaSmc() % 0x3FFF0 << 21), allocates exactly (end - _start) + 1GB.
 
DRAM crt0 mapping (ttbr1): offsets DRAM with (rand64ViaSmc() % 0x3FFF0 << 21), allocates exactly (end - _start) + 1GB.
 
This is a "linear" mapping. Permissions are set properly.
 
This is a "linear" mapping. Permissions are set properly.
Line 111: Line 112:     
Map(RandomizePageBoundary(GuardPage + KCoreContext * 4)) -> NextFreePages(4)
 
Map(RandomizePageBoundary(GuardPage + KCoreContext * 4)) -> NextFreePages(4)
</pre></code>
+
</pre>
    
== 1.0.0 ==
 
== 1.0.0 ==
Line 286: Line 287:  
| All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
 
| All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
 
|}
 
|}
      
The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B.
 
The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B.
Line 314: Line 314:  
|}
 
|}
   −
= Secure Monitor =
+
== Notes ==
 +
=== 2.0.0 ===
 +
  Granule size for TTBR0*_EL1 is 4KB.
 +
  TTBR0_EL1 vmem starts at vaddr 0x0.
 +
  vmem end-addr for TTBR1_EL1 is 0xffffffffffffffff. vmem start-addr for TTBR1_EL1 is 0xFFFFFFF000000000.
 +
  T0SZ = 31. Hence, bit-size of the TTBR0*_EL1 vmem region is 33. (0x0000000200000000)
 +
  T1SZ = 28. Hence, bit-size of the TTBR1*_EL1 vmem region is 36. (0x0000001000000000)
 +
 
 +
  Note: ARM config for TTBR0 is presumably configured for userland later.
 +
 
 +
  See arm-doc for "Table D4-25 Translation table entry addresses when using the 4KB translation granule".
 +
 
 +
  See arm-doc for "Overview of VMSAv8-64 address translation using the 4KB translation granule".
 +
 
 +
  See arm-doc for "Table D4-11 TCR.TnSZ values and IA ranges, 4K granule with no concatenation of tables".
 +
  Both TTBR*_EL1 use "Initial lookup level" 1. Therefore, the TTBR*_EL1 tables are level1.
 +
 
 +
  Due to T*SZ, Stage1/Stage2 translation for the initial table(level1) are the same, except Stage2 uses hard-coded T0SZ.
 +
  Basically, the table is accessed as: ((u64*)tablebase)[<IA[y:30]>], where y = (37-T*SZ)+26. That is, starting at bit "y" ending(inclusive) at bit30. For TTBR0*_EL1, y = 32, while for TTBR1_EL1 y = 35.
 +
  Hence, for TTBR0, index=((vaddr>>30) & 0x7), and for TTBR1, index=((vaddr>>30) & 0x3f).
   −
Unless otherwise mentionned, block descriptors (in our case, the one uses for the DRAM identity mapping) are all ORRed by 0x401 and page descriptors by 0x403.
+
"Vector Base Address Register (EL1)" = 0xfffffff7ffc50800.
 
  −
== [[1.0.0]] ==
     −
{| class="wikitable" border="1"
+
The table for TTBR0 only contains the following:
|-
+
* Vmem 0x80000000 is mapped to physmem 0x80000000, using a size loaded from a register. This is only done when: "endaddr = 0x7fffffff + size; if(endaddr >= 0x80000001){...}"
 +
** The size is loaded from: "(u32 *0x70019050 & 0x3fff) << 20;"
 +
** The value written to the MMU-table descriptor is: "physaddr | val | 0x709;". val is 1<<52 when "tmp>>34" is non-zero and when "if((physaddr & 0x3c0000000) == 0)", otherwise val=0. tmp=size at the start and increased by 0xffffffffc0000000 each loop iteration. physaddr is increased by 0x40000000 each loop iteration.
 +
 
 +
TTBR1:
 +
* vmem 0xFFFFFFF800000000 is mapped to physmem 0x80000000. Similar to above, except tmp=0 due to wrap-around, etc. This also has usermode/kernel XN enabled in the descriptor ORR-value. The chunksize used when increasing addr is 0xfffffff840000000, with another +=0x40000000 separate from the addr cmp for the loop.
 +
** "endaddr = 0x3fffffff + (<size from above> | 0xfffffff800000000); enaddr = (endaddr & 0xffffffffc0000000)-1; if(endaddr >= 0xfffffff800000001){<map mem>}"
 +
 
 +
* Initializes level2 pagetable descriptor for vmem 0xFFFFFFF7C0000000. descriptor = 0x3 | physaddr. physaddr is core-specific.
 +
* Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFC00000. descriptor = 0x3 | physaddr. physaddr is core-specific.
 +
* The content of the pagetable for the following level3 mmutables are not initialized in the main mmutable-init func. descriptor = 0x8007c003(0x3 | <physaddr tablebase>). tablebase=0x8007c000.
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEE00000. physaddr = tablebase + (0x1<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF000000. physaddr = tablebase + (0x2<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF200000. physaddr = tablebase + (0x3<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFA00000. physaddr = tablebase + (0x7<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEC00000. physaddr = tablebase.
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF400000. physaddr = tablebase + (0x4<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF600000. physaddr = tablebase + (0x5<<12).
 +
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF800000. physaddr = tablebase + (0x6<<12).
 +
 
 +
= Secure Monitor =
 +
Unless otherwise mentionned, block descriptors (in our case, the one uses for the DRAM identity mapping) are all ORRed by 0x401 and page descriptors by 0x403.
 +
 
 +
== [[1.0.0]] ==
 +
{| class="wikitable" border="1"
 +
|-
 
! Vmem
 
! Vmem
 
! Physmem
 
! Physmem
Line 848: Line 890:  
| 0x2000
 
| 0x2000
 
| 0x40000000000304
 
| 0x40000000000304
| Undocumented/Not Present (Security Engine for Mariko?)
+
| Erista: Nothing Present, Mariko: Security Engine 2
 
|-
 
|-
 
| 0x1F0092000
 
| 0x1F0092000
Line 1,005: Line 1,047:  
| 0x40000000000300
 
| 0x40000000000300
 
| TZRAM (L3 Page Table)
 
| TZRAM (L3 Page Table)
|-
   
|}
 
|}
   Line 1,083: Line 1,124:  
| 0x2000
 
| 0x2000
 
| 0x40000000000304
 
| 0x40000000000304
| Undocumented/Not Present (Security Engine for Mariko?)
+
| Erista: Nothing Present, Mariko: Security Engine 2
 
|-
 
|-
 
| 0x1F0092000
 
| 0x1F0092000
Line 1,240: Line 1,281:  
| 0x40000000000300
 
| 0x40000000000300
 
| TZRAM (L3 Page Table)
 
| TZRAM (L3 Page Table)
|-
   
|}
 
|}
   Line 1,247: Line 1,287:  
During boot, the BootROM saves the BCT in IRAM at address 0x40000100. The preceding 0x100 bytes (IRAM memory range from 0x40000000 to 0x40000100) contain a structure called BIT (Boot Info Table) which encapsulates the BCT in IRAM and is initialized by the BootROM as follows:
 
During boot, the BootROM saves the BCT in IRAM at address 0x40000100. The preceding 0x100 bytes (IRAM memory range from 0x40000000 to 0x40000100) contain a structure called BIT (Boot Info Table) which encapsulates the BCT in IRAM and is initialized by the BootROM as follows:
    +
=== Erista ===
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 1,256: Line 1,297:  
|  0x00
 
|  0x00
 
|  0x04
 
|  0x04
br_version
+
BootRomVersion
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|-
 
|-
 
|  0x04
 
|  0x04
 
|  0x04
 
|  0x04
bd_version
+
DataVersion
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|-
 
|-
 
|  0x08
 
|  0x08
 
|  0x04
 
|  0x04
rcm_version
+
RcmVersion
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).  
 
|-
 
|-
 
|  0x0C
 
|  0x0C
 
|  0x04
 
|  0x04
boot_type
+
BootType
 
|
 
|
  BOOT_TYPE_COLD = 1
+
  None = 0
  BOOT_TYPE_RECOVERY = 2
+
Cold = 1
  BOOT_TYPE_UART = 3
+
  Recovery = 2
  BOOT_TYPE_EXIT_RCM = 4
+
  Uart = 3
 +
  ExitRcm = 4
 
|-
 
|-
 
|  0x10
 
|  0x10
 
|  0x04
 
|  0x04
unk0
+
PrimaryDevice
|  Set to 0x05 on coldboot.  
+
|  Set to 0x05 (IROM) on coldboot.  
 
|-
 
|-
 
|  0x14
 
|  0x14
 
|  0x04
 
|  0x04
boot_device_type
+
SecondaryDevice
|
+
| Set to 0x04 (SDMMC) on coldboot.
 
|-
 
|-
 
|  0x18
 
|  0x18
|  0x04
+
0x04*0x04
boot_start_time
+
BootTimeLog
Value from TIMERUS_CNTR_1US when the BootROM enters its main function.
+
|   
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  BootTimeLogInit
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  BootTimeLogExit
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  BootReadBctTickCnt
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  BootReadBLTickCnt
 +
|}
 
|-
 
|-
0x1C
+
0x28
 
|  0x04
 
|  0x04
unk1
+
OscFrequency
+
|  Value from CLK_RST_CONTROLLER_OSC_CTRL.  
|-
  −
|  0x20
  −
|  0x04
  −
|  boot_read_bct_time
  −
|  Time spent reading the BCT.
  −
|-
  −
|  0x24
  −
|  0x04
  −
|  boot_parse_bootloader_time
  −
|  Time spent parsing the bootloader info from the BCT.
  −
|-
  −
|  0x28
  −
|  0x04
  −
|  osc_freq
  −
|  Value from CLK_RST_CONTROLLER_OSC_CTRL.  
   
|-
 
|-
 
|  0x2C
 
|  0x2C
 
|  0x01
 
|  0x01
is_boot_device_loaded
+
DevInitialized
 
|  Set to 1 after the boot device is initialized.
 
|  Set to 1 after the boot device is initialized.
 
|-
 
|-
 
|  0x2D
 
|  0x2D
 
|  0x01
 
|  0x01
is_sdram_configured
+
SdramInitialized
 
|  Set to 1 after the SDRAM parameters are parsed.
 
|  Set to 1 after the SDRAM parameters are parsed.
 
|-
 
|-
 
|  0x2E
 
|  0x2E
 
|  0x01
 
|  0x01
is_forced_rcm_pmc
+
ClearedForceRecovery
 
|  Set to 1 if bit 2 was set in APBDEV_PMC_SCRATCH0.
 
|  Set to 1 if bit 2 was set in APBDEV_PMC_SCRATCH0.
 
|-
 
|-
 
|  0x2F
 
|  0x2F
 
|  0x01
 
|  0x01
is_enable_fail_back_pmc
+
ClearedFailBack
 
|  Set to 1 if bit 4 was set in APBDEV_PMC_SCRATCH0.
 
|  Set to 1 if bit 4 was set in APBDEV_PMC_SCRATCH0.
 
|-
 
|-
 
|  0x30
 
|  0x30
0x02
+
0x01
is_bootloader_version_mismatch
+
InvokedFailBack
 
|  Set to 1 if the bootloaders have different versions in the BCT.
 
|  Set to 1 if the bootloaders have different versions in the BCT.
 +
|-
 +
|  0x31
 +
|  0x01
 +
|  IRomPatchStatus
 +
 
|-
 
|-
 
|  0x32
 
|  0x32
0x02
+
0x01
is_bct_valid
+
BctValid
 
|  Set to 1 if the BCT was parsed successfully.
 
|  Set to 1 if the BCT was parsed successfully.
 
|-
 
|-
0x34
+
0x33
0x04
+
0x09
unk2
+
BctStatus
+
Each bit contains the status for BCT reads in a given block.
|-
  −
|  0x38
  −
|  0x04
  −
|  unk3
  −
|   
   
|-
 
|-
 
|  0x3C
 
|  0x3C
 
|  0x04
 
|  0x04
active_bootloader_idx
+
BctLastJournalRead
Value from 0 to 3 that represents which bootloader is active.
+
Contains the status of the last journal block read.
 +
None = 0
 +
Success = 1
 +
ValidationFailure = 2
 +
DeviceReadError = 3
 
|-
 
|-
 
|  0x40
 
|  0x40
 
|  0x04
 
|  0x04
bct_start_block
+
BctBlock
 
|  Block number where the BCT was found.
 
|  Block number where the BCT was found.
 
|-
 
|-
 
|  0x44
 
|  0x44
 
|  0x04
 
|  0x04
bct_start_page
+
BctPage
 
|  Page number where the BCT was found.
 
|  Page number where the BCT was found.
 
|-
 
|-
 
|  0x48
 
|  0x48
 
|  0x04
 
|  0x04
bct_size
+
BctSize
 
|  Size of the BCT in IRAM (0x2800).  
 
|  Size of the BCT in IRAM (0x2800).  
 
|-
 
|-
 
|  0x4C
 
|  0x4C
 
|  0x04
 
|  0x04
bct_ptr
+
BctPtr
 
|  Pointer to the BCT in IRAM (0x40000100).  
 
|  Pointer to the BCT in IRAM (0x40000100).  
 
|-
 
|-
 
|  0x50
 
|  0x50
|  0x18*4
+
|  0x18*0x04
bootloader_headers[4]
+
BlState
|
+
| Contains the state of attempts to load each bootloader.
 
  {| class="wikitable" border="1"
 
  {| class="wikitable" border="1"
 
  |-
 
  |-
Line 1,390: Line 1,443:  
  |  0x00
 
  |  0x00
 
  |  0x04
 
  |  0x04
  |  bootloader_idx
+
  |  Status
 
  |-
 
  |-
 
  |  0x04
 
  |  0x04
 
  |  0x04
 
  |  0x04
  |  bootloader_start_block
+
  |  FirstEccBlock
 
  |-
 
  |-
 
  |  0x08
 
  |  0x08
 
  |  0x04
 
  |  0x04
  |  bootloader_start_page
+
  |  FirstEccPage
 
  |-
 
  |-
 
  |  0x0C
 
  |  0x0C
 
  |  0x04
 
  |  0x04
  |  bootloader_length
+
  |  FirstCorrectedEccBlock
 
  |-
 
  |-
 
  |  0x10
 
  |  0x10
 
  |  0x04
 
  |  0x04
  |  bootloader_signed_start
+
  |  FirstCorrectedEccPage
 
  |-
 
  |-
 
  |  0x14
 
  |  0x14
  |  0x04
+
  |  0x01
  |  bootloader_signature
+
  |  HadEccError
 +
|-
 +
|  0x15
 +
|  0x01
 +
|  HadCrcError
 +
|-
 +
|  0x16
 +
|  0x01
 +
|  HadCorrectedEccError
 +
|-
 +
|  0x17
 +
|  0x01
 +
|  UsedForEccRecovery
 
  |}
 
  |}
 
|-
 
|-
 
|  0xB0
 
|  0xB0
0x40
+
0x3C
boot_device_info
+
SecondaryDevStatus
|  Structure to hold boot device parameters.
+
|  Structure to hold secondary boot device status.
|-
+
For SDMMC, the following applies:
|  0xF0
+
{| class="wikitable" border="1"
|  0x04
+
|-
bct_end_ptr
+
!  Offset
|  Pointer to the end of the BCT in IRAM (0x40002900).
+
!  Size
|-
+
!  Field
|  0xF4
+
|-
|  0x0C
+
|  0x00
padding
+
|  0x01
|  Must be empty.
+
|  FuseDataWidth
|}
+
|-
 
+
|  0x01
= Notes =
+
|  0x01
== 2.0.0 ==
+
|  FuseVoltageRange
  Granule size for TTBR0*_EL1 is 4KB.
+
|-
  TTBR0_EL1 vmem starts at vaddr 0x0.
+
|  0x02
  vmem end-addr for TTBR1_EL1 is 0xffffffffffffffff. vmem start-addr for TTBR1_EL1 is 0xFFFFFFF000000000.
+
|  0x01
  T0SZ = 31. Hence, bit-size of the TTBR0*_EL1 vmem region is 33. (0x0000000200000000)
+
|  FuseDisableBootMode
  T1SZ = 28. Hence, bit-size of the TTBR1*_EL1 vmem region is 36. (0x0000001000000000)
+
|-
 
+
|  0x03
  Note: ARM config for TTBR0 is presumably configured for userland later.
+
|  0x01
 
+
|  FuseDdrMode
  See arm-doc for "Table D4-25 Translation table entry addresses when using the 4KB translation granule".
+
|-
 
+
|  0x04
  See arm-doc for "Overview of VMSAv8-64 address translation using the 4KB translation granule".
+
|  0x01
 
+
|  DiscoveredCardType
  See arm-doc for "Table D4-11 TCR.TnSZ values and IA ranges, 4K granule with no concatenation of tables".
+
|-
  Both TTBR*_EL1 use "Initial lookup level" 1. Therefore, the TTBR*_EL1 tables are level1.
+
|  0x05
 
+
|  0x03
  Due to T*SZ, Stage1/Stage2 translation for the initial table(level1) are the same, except Stage2 uses hard-coded T0SZ.
+
|  Reserved
  Basically, the table is accessed as: ((u64*)tablebase)[<IA[y:30]>], where y = (37-T*SZ)+26. That is, starting at bit "y" ending(inclusive) at bit30. For TTBR0*_EL1, y = 32, while for TTBR1_EL1 y = 35.
+
|-
  Hence, for TTBR0, index=((vaddr>>30) & 0x7), and for TTBR1, index=((vaddr>>30) & 0x3f).
+
|  0x08
 +
|  0x04
 +
|  DiscoveredVoltageRange
 +
|-
 +
|  0x0C
 +
|  0x01
 +
|  DataWidthUnderUse
 +
|-
 +
|  0x0D
 +
|  0x01
 +
|  PowerClassUnderUse
 +
|-
 +
|  0x0E
 +
|  0x01
 +
|  AutoCalStatus
 +
|-
 +
|  0x0F
 +
|  0x01
 +
|  Reserved
 +
|-
 +
|  0x10
 +
|  0x10
 +
|  Cid
 +
|-
 +
|  0x20
 +
|  0x04
 +
|  NumPagesRead
 +
|-
 +
|  0x24
 +
|  0x04
 +
|  NumCrcErrors
 +
|-
 +
|  0x25
 +
|  0x01
 +
|  BootFromBootPartition
 +
|-
 +
|  0x26
 +
|  0x01
 +
|  BootModeReadSuccessful
 +
|-
 +
|  0x27
 +
|  0x15
 +
|  Reserved
 +
|}
 +
|-
 +
|  0xEC
 +
|  0x04
 +
|  UsbChargingStatus
 +
 +
|-
 +
|  0xF0
 +
|  0x04
 +
SafeStartAddr
 +
|  Pointer to the end of the BCT in IRAM (0x40002900).
 +
|-
 +
|  0xF4
 +
|  0x0C
 +
Reserved
 +
|  Must be empty.
 +
|}
 +
 
 +
=== Mariko ===
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
!  Description
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  BootRomVersion
 +
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  DataVersion
 +
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  RcmVersion
 +
|  Set to 0x00210001 (BOOTDATA_VERSION_T210).
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  BootType
 +
|
 +
None = 0
 +
Cold = 1
 +
Recovery = 2
 +
Uart = 3
 +
ExitRcm = 4
 +
|-
 +
|  0x10
 +
|  0x04
 +
|  PrimaryDevice
 +
|  Set to 0x05 (IROM) on coldboot.  
 +
|-
 +
|  0x14
 +
|  0x04
 +
|  SecondaryDevice
 +
|  Set to 0x04 (SDMMC) on coldboot.  
 +
|-
 +
|  0x18
 +
|  0x04
 +
|  AuthenticationScheme
 +
 +
|-
 +
|  0x1C
 +
|  0x01
 +
|  EncryptionEnabled
 +
 +
|-
 +
|  0x1D
 +
|  0x03
 +
|  Reserved
 +
 +
|-
 +
|  0x20
 +
|  0x04
 +
|  BootROMtracker
 +
 +
|-
 +
|  0x24
 +
|  0x05*0x04
 +
|  BootTimeLog
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  BootTimeLogInit
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  BootTimeLogExit
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  BootSetupTickCnt
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  BootReadBctTickCnt
 +
|-
 +
|  0x10
 +
|  0x04
 +
|  BootReadBLTickCnt
 +
|}
 +
|-
 +
|  0x38
 +
|  0x10*0x28
 +
|  BootFlowLog
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  BootFlowLogInit
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  BootFlowLogExit
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  BootFlowFuncId
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  BootFlowFuncStatus
 +
|}
 +
|-
 +
|  0x2B8
 +
|  0x04
 +
|  OscFrequency
 +
|  Value from CLK_RST_CONTROLLER_OSC_CTRL.
 +
|-
 +
|  0x2BC
 +
|  0x01
 +
|  DevInitialized
 +
|  Set to 1 after the boot device is initialized.
 +
|-
 +
|  0x2BD
 +
|  0x01
 +
|  SdramInitialized
 +
|  Set to 1 after the SDRAM parameters are parsed.
 +
|-
 +
|  0x2BE
 +
|  0x01
 +
|  ClearedForceRecovery
 +
|  Set to 1 if bit 2 was set in APBDEV_PMC_SCRATCH0.
 +
|-
 +
|  0x2BF
 +
|  0x01
 +
|  ClearedFailBack
 +
|  Set to 1 if bit 4 was set in APBDEV_PMC_SCRATCH0.
 +
|-
 +
|  0x2C0
 +
|  0x01
 +
|  InvokedFailBack
 +
|  Set to 1 if the bootloaders have different versions in the BCT.
 +
|-
 +
|  0x2C1
 +
|  0x01
 +
|  IRomPatchStatus
 +
 +
|-
 +
|  0x2C2
 +
|  0x01
 +
|  BctSizeValid
 +
 +
|-
 +
|  0x2C3
 +
|  0x09
 +
|  BctSizeStatus
 +
 +
|-
 +
|  0x2CC
 +
|  0x04
 +
|  BctSizeLastJournalRead
 +
 +
|-
 +
|  0x2D0
 +
|  0x04
 +
|  BctSizeBlock
 +
 +
|-
 +
|  0x2D4
 +
|  0x04
 +
|  BctSizePage
 +
 +
|-
 +
|  0x2D8
 +
|  0x01
 +
|  BctValid
 +
|  Set to 1 if the BCT was parsed successfully.
 +
|-
 +
|  0x2D9
 +
|  0x09
 +
|  BctStatus
 +
|  Each bit contains the status for BCT reads in a given block.
 +
|-
 +
|  0x2E2
 +
|  0x02
 +
|  Reserved
 +
 +
|-
 +
|  0x2E4
 +
|  0x04
 +
|  BctLastJournalRead
 +
|  Contains the status of the last journal block read.
 +
None = 0
 +
Success = 1
 +
ValidationFailure = 2
 +
DeviceReadError = 3
 +
|-
 +
|  0x2E8
 +
|  0x04
 +
|  BctBlock
 +
|  Block number where the BCT was found.
 +
|-
 +
|  0x2EC
 +
|  0x04
 +
|  BctPage
 +
|  Page number where the BCT was found.
 +
|-
 +
|  0x2F0
 +
|  0x04
 +
|  BctSize
 +
|  Size of the BCT in IRAM.
 +
|-
 +
|  0x2F4
 +
|  0x04
 +
|  BctPtr
 +
|  Pointer to the BCT in IRAM.
 +
|-
 +
|  0x2F8
 +
|  0x18*0x04
 +
|  BlState
 +
|  Contains the state of attempts to load each bootloader.
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  Status
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  FirstEccBlock
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  FirstEccPage
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  FirstCorrectedEccBlock
 +
|-
 +
|  0x10
 +
|  0x04
 +
|  FirstCorrectedEccPage
 +
|-
 +
|  0x14
 +
|  0x01
 +
|  HadEccError
 +
|-
 +
|  0x15
 +
|  0x01
 +
|  HadCrcError
 +
|-
 +
|  0x16
 +
|  0x01
 +
|  HadCorrectedEccError
 +
|-
 +
|  0x17
 +
|  0x01
 +
|  UsedForEccRecovery
 +
|}
 +
|-
 +
|  0x358
 +
|  0x100
 +
|  SecondaryDevStatus
 +
|  Structure to hold secondary boot device status.
 +
|-
 +
|  0x458
 +
|  0x03
 +
|  Reserved
 +
 +
|-
 +
|  0x45B
 +
|  0x04
 +
|  UsbChargingStatus
 +
 +
|-
 +
|  0x45F
 +
|  0x01
 +
|  PmuBootSelReadError
 +
 +
|-
 +
|  0x460
 +
|  0x04
 +
|  SafeStartAddr
 +
|  Pointer to the end of the BCT in IRAM.
 +
|}
 +
 
 +
= Carveouts =
 +
The MC (Memory Controller) provides multiple configurable memory carveouts which allow to protect and limit access to sensitive DRAM regions. Carveouts work on the physical access level, thus acting as the last protection barrier from unauthorized memory accesses.
 +
 
 +
A total of 9 programmable carveouts are available from which 4 have a fixed function (TZDRAM, VPR, SEC and MTS) and 5 are generalized carevouts (GSCs 1 to 5).
 +
 
 +
== TZDRAM Carveout ==
 +
Defines a DRAM region that can only be accessed by TrustZone-secure clients. Currently unused by the Switch.
 +
 
 +
This carveout is controlled by the following MC registers:
 +
<pre>
 +
MC_SECURITY_CFG0
 +
MC_SECURITY_CFG1
 +
MC_SECURITY_CFG3
 +
</pre>
 +
 
 +
== VPR Carveout ==
 +
Defines a DRAM region that can only be accessed by clients that are part of the video decode and display process (Display, GPU, TSEC, VIC, NVENC, NVDEC and HDA). Currently unused by the Switch.
 +
 
 +
This carveout is controlled by the following MC registers:
 +
<pre>
 +
MC_VIDEO_PROTECT_GPU_OVERRIDE_0
 +
MC_VIDEO_PROTECT_GPU_OVERRIDE_1
 +
MC_VIDEO_PROTECT_BOM
 +
MC_VIDEO_PROTECT_SIZE_MB
 +
MC_VIDEO_PROTECT_REG_CTRL
 +
</pre>
 +
 
 +
== SEC Carveout ==
 +
Defines a DRAM region that can only be accessed by the [[#TSEC|TSEC]]. Deprecated and unused by the Switch.
 +
 
 +
This carveout is controlled by the following MC registers:
 +
<pre>
 +
MC_SEC_CARVEOUT_BOM
 +
MC_SEC_CARVEOUT_SIZE_MB
 +
MC_SEC_CARVEOUT_REG_CTRL
 +
</pre>
 +
 
 +
== MTS Carveout ==
 +
Defines a DRAM region for Falcon microcode. Deprecated and unused by the Switch.
 +
 
 +
This carveout is controlled by the following MC registers:
 +
<pre>
 +
MC_MTS_CARVEOUT_BOM
 +
MC_MTS_CARVEOUT_SIZE_MB
 +
MC_MTS_CARVEOUT_ADR_HI
 +
MC_MTS_CARVEOUT_REG_CTRL
 +
</pre>
 +
 
 +
== Generalized Carveouts ==
 +
These carveouts can be freely configured for any client that supports them.
 +
 
 +
These carveouts are controlled by the following MC registers:
 +
<pre>
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_BOM
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_BOM_HI
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_SIZE_128KB
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_ACCESS0
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_ACCESS1
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_ACCESS2
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_ACCESS3
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_ACCESS4
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_FORCE_INTERNAL_ACCESS0
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_FORCE_INTERNAL_ACCESS1
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_FORCE_INTERNAL_ACCESS2
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_FORCE_INTERNAL_ACCESS3
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CLIENT_FORCE_INTERNAL_ACCESS4
 +
MC_SECURITY_CARVEOUT1/2/3/4/5_CFG0
 +
</pre>
 +
 
 +
The client access registers (CLIENT_ACCESS0/1/2/3/4) are used to whitelist accesses from MC clients as follows:
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  ClientAccess0
 +
!  ClientAccess1
 +
!  ClientAccess2
 +
!  ClientAccess3
 +
!  ClientAccess4
 +
|-
 +
| 0
 +
| CSR_PTCR
 +
| Reserved
 +
| CSW_VDEMBEW
 +
| CSR_SDMMCRA
 +
| CSR_SESRD
 +
|-
 +
| 1
 +
| CSR_DISPLAY0A
 +
| Reserved
 +
| CSW_VDETPMW
 +
| CSR_SDMMCRAA
 +
| CSW_SESWR
 +
|-
 +
| 2
 +
| CSR_DISPLAY0AB
 +
| CSR_VDEBSEVR
 +
| Reserved
 +
| CSR_SDMMCR
 +
| CSR_AXIAPR
 +
|-
 +
| 3
 +
| CSR_DISPLAY0B
 +
| CSR_VDEMBER
 +
| Reserved
 +
| CSR_SDMMCRAB
 +
| CSW_AXIAPW
 +
|-
 +
| 4
 +
| CSR_DISPLAY0BB
 +
| CSR_VDEMCER
 +
| CSR_ISPRA
 +
| CSW_SDMMCWA
 +
| CSR_ETRR
 +
|-
 +
| 5
 +
| CSR_DISPLAY0C
 +
| CSR_VDETPER
 +
| Reserved
 +
| CSW_SDMMCWAA
 +
| CSW_ETRW
 +
|-
 +
| 6
 +
| CSR_DISPLAY0CB
 +
| CSR_MPCORELPR
 +
| CSW_ISPWA
 +
| CSW_SDMMCW
 +
| CSR_TSECSRDB
 +
|-
 +
| 7
 +
| Reserved
 +
| CSR_MPCORER
 +
| CSW_ISPWB
 +
| CSW_SDMMCWAB
 +
| CSW_TSECSWRB
 +
|-
 +
| 8
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| CSR_GPUSRD2
 +
|-
 +
| 9
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| CSW_GPUSWR2
 +
|-
 +
| 10
 +
| Reserved
 +
| Reserved
 +
| CSR_XUSB_HOSTR
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 11
 +
| Reserved
 +
| CSW_NVENCSWR
 +
| CSW_XUSB_HOSTW
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 12
 +
| Reserved
 +
| Reserved
 +
| CSR_XUSB_DEVR
 +
| CSR_VICSRD
 +
| Reserved
 +
|-
 +
| 13
 +
| Reserved
 +
| Reserved
 +
| CSW_XUSB_DEVW
 +
| CSW_VICSWR
 +
| Reserved
 +
|-
 +
| 14
 +
| CSR_AFIR
 +
| Reserved
 +
| CSR_ISPRAB (Erista) or CSR_SE2SRD (Mariko)
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 15
 +
| CSR_AVPCARM7R
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 16
 +
| CSR_DISPLAYHC
 +
| Reserved
 +
| CSW_ISPWAB (Erista) or CSW_SE2SWR (Mariko)
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 17
 +
| CSR_DISPLAYHCB
 +
| CSW_AFIW
 +
| CSW_ISPWBB (Erista) or Reserved (Mariko)
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 18
 +
| Reserved
 +
| CSW_AVPCARM7W
 +
| Reserved
 +
| CSW_VIW
 +
| Reserved
 +
|-
 +
| 19
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
| CSR_DISPLAYD
 +
| Reserved
 +
|-
 +
| 20
 +
| Reserved
 +
| Reserved
 +
| CSR_TSECSRD
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 21
 +
| CSR_HDAR
 +
| CSW_HDAW
 +
| CSW_TSECSWR
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 22
 +
| CSR_HOST1XDMAR
 +
| CSW_HOST1XW
 +
| CSR_A9AVPSCR
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 23
 +
| CSR_HOST1XR
 +
| Reserved
 +
| CSW_A9AVPSCW
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 24
 +
| Reserved
 +
| CSW_MPCORELPW
 +
| CSR_GPUSRD
 +
| CSR_NVDECSRD
 +
| Reserved
 +
|-
 +
| 25
 +
| Reserved
 +
| CSW_MPCOREW
 +
| CSW_GPUSWR
 +
| CSW_NVDECSWR
 +
| Reserved
 +
|-
 +
| 26
 +
| Reserved
 +
| Reserved
 +
| CSR_DISPLAYT
 +
| CSR_APER
 +
| Reserved
 +
|-
 +
| 27
 +
| Reserved
 +
| CSW_PPCSAHBDMAW
 +
| Reserved
 +
| CSW_APEW
 +
| Reserved
 +
|-
 +
| 28
 +
| CSR_NVENCSRD
 +
| CSW_PPCSAHBSLVW
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 29
 +
| CSR_PPCSAHBDMAR
 +
| CSW_SATAW
 +
| Reserved
 +
| Reserved
 +
| Reserved
 +
|-
 +
| 30
 +
| CSR_PPCSAHBSLVR
 +
| CSW_VDEBSEVW
 +
| Reserved
 +
| CSR_NVJPGSRD
 +
| Reserved
 +
|-
 +
| 31
 +
| CSR_SATAR
 +
| CSW_VDEDBGW
 +
| Reserved
 +
| CSW_NVJPGSWR
 +
| Reserved
 +
|}
 +
 
 +
The configuration register (CFG0) is used to control the carveout's properties as follows:
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| PROTECT_MODE
 +
0: LOCKBIT_SECURE (registers cannot be modified after lock down)
 +
1: TZ_SECURE (registers can be modified by TZ after lock down)
 +
|-
 +
| 1
 +
| LOCK_MODE
 +
0: UNLOCKED (registers can be modified at any time)
 +
1: LOCKED (registers cannot be modified until reset)
 +
|-
 +
| 2
 +
| ADDRESS_TYPE
 +
0: ANY_ADDRESS
 +
1: UNTRANSLATED_ONLY
 +
|-
 +
| 3-6
 +
| READ_ACCESS_LEVEL
 +
Bit 0: Access level 0 (default for all clients)
 +
Bit 1: Access level 1 (unknown)
 +
Bit 2: Access level 2 (Falcon clients in LS mode)
 +
Bit 3: Access level 3 (Falcon clients in HS mode)
 +
|-
 +
| 7-10
 +
| WRITE_ACCESS_LEVEL
 +
Bit 0: Access level 0 (default for all clients)
 +
Bit 1: Access level 1 (unknown)
 +
Bit 2: Access level 2 (Falcon clients in LS mode)
 +
Bit 3: Access level 3 (Falcon clients in HS mode)
 +
|-
 +
| 11-13
 +
| APERTURE_ID
 +
|-
 +
| 14-17
 +
| DISABLE_READ_CHECK_ACCESS_LEVEL
 +
Bit 0: Disable read access level 0 check
 +
Bit 1: Disable read access level 1 check
 +
Bit 2: Disable read access level 2 check
 +
Bit 3: Disable read access level 3 check
 +
|-
 +
| 18-21
 +
| DISABLE_WRITE_CHECK_ACCESS_LEVEL
 +
Bit 0: Disable write access level 0 check
 +
Bit 1: Disable write access level 1 check
 +
Bit 2: Disable write access level 2 check
 +
Bit 3: Disable write access level 3 check
 +
|-
 +
| 22
 +
| SEND_CFG_TO_GPU
 +
0: DISABLED
 +
1: ENABLED
 +
|-
 +
| 23
 +
| TZ_GLOBAL_WR_EN
 +
0: DISABLED
 +
1: BYPASS_CHECK
 +
|-
 +
| 24
 +
| TZ_GLOBAL_RD_EN
 +
0: DISABLED
 +
1: BYPASS_CHECK
 +
|-
 +
| 25
 +
| ALLOW_APERTURE_ID_MISMATCH
 +
0: DISABLED
 +
1: ENABLED
 +
|-
 +
| 26
 +
| FORCE_APERTURE_ID_MATCH
 +
0: DISABLED
 +
1: ENABLED
 +
|-
 +
| 27
 +
| IS_WPR
 +
0: DISABLED
 +
1: ENABLED
 +
|}
 +
 
 +
=== GSC1 ===
 +
This carveout is, by default, for NVDEC. In the Switch's case, this carveout is not used.
 +
 
 +
It is configured as follows:
 +
<pre>
 +
*(u32 *)MC_SECURITY_CARVEOUT1_BOM = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_BOM_HI = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_SIZE_128KB = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT1_CFG0 = 0x4000006;
 +
</pre>
 +
 
 +
=== GSC2 ===
 +
This carveout is, by default and in the Switch's case, for the GPU (WPR1).
 +
 
 +
It is configured as follows:
 +
<pre>
 +
*(u32 *)MC_SECURITY_CARVEOUT2_BOM = 0x80020000;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_BOM_HI = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_SIZE_128KB = 2;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 = 0x3000000;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 = 0x300;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT2_CFG0 = 0x440167E;
 +
</pre>
 +
 
 +
=== GSC3 ===
 +
This carveout is, by default, for the GPU (WPR2). In the Switch's case, this carveout is not used.
 +
 
 +
It is configured as follows:
 +
<pre>
 +
*(u32 *)MC_SECURITY_CARVEOUT3_BOM = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_BOM_HI = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_SIZE_128KB = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 = 0x3000000;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 = 0x300;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT3_CFG0 = 0x4401E7E;
 +
</pre>
 +
 
 +
=== GSC4 ===
 +
This carveout is, by default, for TSECA. In the Switch's case, this carveout is used by the Kernel.
 +
 
 +
It is initially configured as follows:
 +
<pre>
 +
*(u32 *)MC_SECURITY_CARVEOUT4_BOM = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_BOM_HI = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_SIZE_128KB = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT4_CFG0 = 0x8F;
 +
</pre>
   −
"Vector Base Address Register (EL1)" = 0xfffffff7ffc50800.
+
Then further configured using [[SMC#ConfigureCarveout|smcConfigureCarveout]].
   −
The table for TTBR0 only contains the following:
+
=== GSC5 ===
* Vmem 0x80000000 is mapped to physmem 0x80000000, using a size loaded from a register. This is only done when: "endaddr = 0x7fffffff + size; if(endaddr >= 0x80000001){...}"
+
This carveout is, by default, for TSECB. In the Switch's case, this carveout is used by the Kernel.
** The size is loaded from: "(u32 *0x70019050 & 0x3fff) << 20;"
  −
** The value written to the MMU-table descriptor is: "physaddr | val | 0x709;". val is 1<<52 when "tmp>>34" is non-zero and when "if((physaddr & 0x3c0000000) == 0)", otherwise val=0. tmp=size at the start and increased by 0xffffffffc0000000 each loop iteration. physaddr is increased by 0x40000000 each loop iteration.
     −
TTBR1:
+
It is initially configured as follows:
* vmem 0xFFFFFFF800000000 is mapped to physmem 0x80000000. Similar to above, except tmp=0 due to wrap-around, etc. This also has usermode/kernel XN enabled in the descriptor ORR-value. The chunksize used when increasing addr is 0xfffffff840000000, with another +=0x40000000 separate from the addr cmp for the loop.
+
<pre>
** "endaddr = 0x3fffffff + (<size from above> | 0xfffffff800000000); enaddr = (endaddr & 0xffffffffc0000000)-1; if(endaddr >= 0xfffffff800000001){<map mem>}"
+
*(u32 *)MC_SECURITY_CARVEOUT5_BOM = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_BOM_HI = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_SIZE_128KB = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 = 0;
 +
*(u32 *)MC_SECURITY_CARVEOUT5_CFG0 = 0x8F;
 +
</pre>
   −
* Initializes level2 pagetable descriptor for vmem 0xFFFFFFF7C0000000. descriptor = 0x3 | physaddr. physaddr is core-specific.
+
Then further configured using [[SMC#ConfigureCarveout|smcConfigureCarveout]].
* Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFC00000. descriptor = 0x3 | physaddr. physaddr is core-specific.
  −
* The content of the pagetable for the following level3 mmutables are not initialized in the main mmutable-init func. descriptor = 0x8007c003(0x3 | <physaddr tablebase>). tablebase=0x8007c000.
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEE00000. physaddr = tablebase + (0x1<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF000000. physaddr = tablebase + (0x2<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF200000. physaddr = tablebase + (0x3<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFA00000. physaddr = tablebase + (0x7<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEC00000. physaddr = tablebase.
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF400000. physaddr = tablebase + (0x4<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF600000. physaddr = tablebase + (0x5<<12).
  −
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF800000. physaddr = tablebase + (0x6<<12).