Changes

Jump to navigation Jump to search
36,197 bytes added ,  16:33, 11 June 2020
Line 3: Line 3:     
There are two regions randomized and enforced by the kernel, each one with upper bits random and 2MB-aligned:
 
There are two regions randomized and enforced by the kernel, each one with upper bits random and 2MB-aligned:
* Heap region, available from [[SVC#svcGetInfo]].
+
* ReservedHeapRegion, available from [[SVC#svcGetInfo]].
* Stack mapping region, available from [[SVC#svcGetInfo]].
+
* ReservedMapRegion, available from [[SVC#svcGetInfo]].
 +
* [2.0.0+] NewReservedMapRegion, available from [[SVC#svcGetInfo]].
 +
* [2.0.0+] TlsIoRegion, not available to userspace.
    
The main binary is placed at an address that is provided to the kernel by Loader via [[SVC#svcCreateProcess]].
 
The main binary is placed at an address that is provided to the kernel by Loader via [[SVC#svcCreateProcess]].
Line 18: Line 20:  
On version [[1.0.0]], the initial binaries loaded into memory by the kernel always have the upper 32-bits as all-zero, so there are 6 fewer bits of layout randomization.  
 
On version [[1.0.0]], the initial binaries loaded into memory by the kernel always have the upper 32-bits as all-zero, so there are 6 fewer bits of layout randomization.  
   −
= Kernel Implementation of Userland ASLR =
+
Binaries loaded within the main-binary-region are loaded into memory in the following order, immediately after each other, for the binaries which exist in [[ExeFS]]:
 +
* rtld
 +
* main
 +
* subsdk*
 +
* sdk
   −
== 1.0.0 ==
+
== ASLR Implementation ==
 +
The kernel uses a MT19937 random number generator, seeded by [[SMC#GetRandomBytes|smcGetRandomBytes]].
 +
 
 +
=== 1.0.0 ===
    
  if (AddressSpaceType == 2) {
 
  if (AddressSpaceType == 2) {
Line 51: Line 60:  
  this->HeapRegionBaseAddr = this->MapBaseAddr + MapRegionSize + max(rnd0, rnd1) - min(rnd0, rnd1)
 
  this->HeapRegionBaseAddr = this->MapBaseAddr + MapRegionSize + max(rnd0, rnd1) - min(rnd0, rnd1)
   −
==TLS==
+
= Kernel =
This is the 0x200-byte thread-local-storage, the base address is loaded via ARM threadid register tpidrro_el0.
+
For more details, see [[#Notes]]. Here comes a summary.
 +
 
 +
PXN bit is set in the MMU descriptor for userland code pages. This means that userland code pages are not executable in kernel mode (this is equivalent to SMEP on x86).
 +
 
 +
For userland pages, the kernel has same access as userland (either both are read-only or both are read-write). It does not have SMAP. The previous rule has one exception: pages that are mapped unreadable in usermode are still forced readable from kernelmode.
 +
 
 +
KASLR is being used since [[5.0.0]], but not before, with the following pseudocode (might contains some errors):
 +
 
 +
<pre>
 +
DRAM crt0 mapping (ttbr1): offsets DRAM with (rand64ViaSmc() % 0x3FFF0 << 21), allocates exactly (end - _start) + 1GB.
 +
This is a "linear" mapping. Permissions are set properly.
 +
 
 +
KERN_ADDRSPACE      := [VA(_start) : min(0xFFFFFFFFFFE00000 - VA(_start), 0x40000000)]
 +
DRAM_FROM_SECTION1  := DRAM[0x808cd000:] // 0x808cd000 corresponds to start of section1 (loaded INI1) data, reused later
 +
 
 +
/* Global Randomize range: 0xFFFFFF8000000000 to 0xFFFFFFFFFFE00000. */
 +
/*
 +
    Randomize picks a random integer in ranges, clears as many low bits required,
 +
    then checks if the address is acceptable, if not it attempts to iterate through page table entries.
 +
   
 +
    If it doesn't find anything, it picks another integer. In case of general failure, the whole operation
 +
    may be done from the start again (maybe ?).
 +
*/
 +
 
 +
/* Core0 executes this big KASLR function, then powers on the other CPUs (?). */
 +
MapPartially(RandomizeL1Boundary(DRAM, sizeof(DRAM)) -> DRAM_FROM_SECTION1: offsetof DRAM_FROM_SECTION1,
 +
 
 +
/* Randomize */
 +
KERN_ADDRSPACE {
 +
    Randomize(IOAndInitialStacks, 0x2000000) {
 +
        Map(Randomize(UartA, 0x1000)) -> UartA,
 +
        GuardPage,
 +
        Map(Randomize(Gicd, 0x1000)) -> Gicd,
 +
        GuardPage,
 +
        Map(Randomize(Gicc, 0x1000)) -> Gicc,
 +
        ForEachCore {
 +
            GuardPage,
 +
            Map(Randomize(EntryThreadStack, 0x1000)) -> NextFreePage(),
 +
            GuardPage,
 +
            Map(Randomize(IdleSchedulerThreadStack, 0x1000)) -> NextFreePage(),
 +
            GuardPage,
 +
            Map(Randomize(EL1AbortStack, 0x1000)) -> NextFreePage(),
 +
        }
 +
    },
 +
   
 +
    Randomize(KernelStacks, 0xE00000),
 +
    Map(Randomize(SlabHeaps, 0x7E9000, AFTER(VA(_end)) -> PA(_end)),
 +
    Randomize(Kip1DecompressionBuffer, 0x8000000), /* 128 MB VA range */
 +
},
 +
 
 +
Map(RandomizePageBoundary(GuardPage + KCoreContext * 4)) -> NextFreePages(4)
 +
</pre>
 +
 
 +
== 1.0.0 ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Virtual || Physical || Size || Attributes || Permissions || Description
 +
|-
 +
| 0xFFFFFFFFBFC00000-0xFFFFFFFFBFC45FFF || 0x800A0000 || 0x46000 || 0x78B || R-X || Kernel .text
 +
|-
 +
| 0xFFFFFFFFBFC46000-0xFFFFFFFFBFC48FFF || 0x800E6000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata
 +
|-
 +
| 0xFFFFFFFFBFC49000-0xFFFFFFFFBFC4FFFF || 0x800E9000 || 0x7000 || 0x6000000000070B || RW- || Kernel .data+.bss
 +
|-
 +
| 0xFFFFFFFFBFD72000-0xFFFFFFFFBFD72FFF || 0x6000F000 || 0x1000 || 0x60000000000607 || RW- || Exception vectors
 +
|-
 +
| 0xFFFFFFFFBFDB5000-0xFFFFFFFFBFDB5FFF || 0x60007000 || 0x1000 || 0x60000000000607 || RW- || Flow controller
 +
|-
 +
| 0xFFFFFFFFBFDB7000-0xFFFFFFFFBFDB7FFF || 0x60004000 || 0x1000 || 0x60000000000607 || RW- || Primary ICTLR
 +
|-
 +
| 0xFFFFFFFFBFDB9000-0xFFFFFFFFBFDB9FFF || 0x60001000 || 0x1000 || 0x60000000000607 || RW- || Resource Semaphore
 +
|-
 +
| 0xFFFFFFFFBFDBB000-0xFFFFFFFFBFDBBFFF || 0x70016000 || 0x2000 || 0x60000000000607 || RW- || ATOMICS
 +
|-
 +
| 0xFFFFFFFFBFDBE000-0xFFFFFFFFBFDBEFFF || 0x7000E000 || 0x1000 || 0x60000000000607 || RW- || PMC
 +
|-
 +
| 0xFFFFFFFFBFDC0000-0xFFFFFFFFBFDC0FFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and reset
 +
|-
 +
| 0xFFFFFFFFBFDC2000-0xFFFFFFFFBFDC2FFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1
 +
|-
 +
| 0xFFFFFFFFBFDC4000-0xFFFFFFFFBFDC4FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0
 +
|-
 +
| 0xFFFFFFFFBFDC6000-0xFFFFFFFFBFDC6FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC
 +
|-
 +
| 0xFFFFFFFFBFDC8000-0xFFFFFFFFBFDC8FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A
 +
|-
 +
| 0xFFFFFFFFBFDCA000-0xFFFFFFFFBFDCBFFF || 0x80060000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| 0xFFFFFFFFBFDCE000-0xFFFFFFFFBFDCFFFF || 0x80068000 || 0x2000 || 0x6000000000070B || RW- || Kernel main stack (cpu0)
 +
|-
 +
| 0xFFFFFFFFBFDD2000-0xFFFFFFFFBFDD2FFF || 0x80070000 || 0x1000 || 0x6000000000070B || RW- || Kernel runner stack (cpu0)
 +
|-
 +
| 0xFFFFFFFFBFDD4000-0xFFFFFFFFBFDD5FFF || 0x80062000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| 0xFFFFFFFFBFDD8000-0xFFFFFFFFBFDD9FFF || 0x8006A000 || 0x2000 || 0x6000000000070B || RW- || Kernel main stack (cpu1)
 +
|-
 +
| 0xFFFFFFFFBFDDC000-0xFFFFFFFFBFDDCFFF || 0x80071000 || 0x1000 || 0x6000000000070B || RW- || Kernel runner stack (cpu1)
 +
|-
 +
| 0xFFFFFFFFBFDDE000-0xFFFFFFFFBFDDFFFF || 0x80064000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| 0xFFFFFFFFBFDE2000-0xFFFFFFFFBFDE3FFF || 0x8006C000 || 0x2000 || 0x6000000000070B || RW- || Kernel main stack (cpu2)
 +
|-
 +
| 0xFFFFFFFFBFDE6000-0xFFFFFFFFBFDE6FFF || 0x80072000 || 0x1000 || 0x6000000000070B || RW- || Kernel runner stack (cpu2)
 +
|-
 +
| 0xFFFFFFFFBFDE8000-0xFFFFFFFFBFDE9FFF || 0x80066000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| 0xFFFFFFFFBFDEC000-0xFFFFFFFFBFDEDFFF || 0x8006E000 || 0x2000 || 0x6000000000070B || RW- || Kernel main stack (cpu3)
 +
|-
 +
| 0xFFFFFFFFBFDF0000-0xFFFFFFFFBFDF0FFF || 0x80073000 || 0x1000 || 0x6000000000070B || RW- || Kernel runner stack (cpu3)
 +
|-
 +
| 0xFFFFFFFFBFDFB000-0xFFFFFFFFBFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor
 +
|-
 +
| 0xFFFFFFFFBFDFD000-0xFFFFFFFFBFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
 +
|-
 +
| 0xFFFFFFFFBFDF2000-0xFFFFFFFFBFDF3FFF || 0x80060000+(cpuid*0x2000) || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| 0xFFFFFFFFBFDF6000-0xFFFFFFFFBFDF7FFF || 0x80068000+(cpuid*0x2000) || 0x2000 || 0x6000000000070B || RW- || Kernel main stack (per-core self-mirror)
 +
|-
 +
| 0xFFFFFFFFBFDFF000-0xFFFFFFFFBFDFFFFF || 0x80084000+(cpuid*0x1000) || 0x1000 || 0x6000000000070B || RW- || Kernel runner stack (per-core self-mirror)
 +
|-
 +
| 0xFFFFFFFE00000000-... || 0x80000000 || ... || 0x60000000000709 || RW- || Raw DRAM access
 +
|}
 +
 
 +
== 2.0.0 ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cores || Virtual || Physical || Size || Attributes || Permissions || Description
 +
|-
 +
| All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC62FFF || 0x800A0000 || 0x63000 || 0x78B || R-X || Kernel .text
 +
|-
 +
| All || 0xFFFFFFF7FFC63000-0xFFFFFFF7FFC65FFF || 0x80103000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata
 +
|-
 +
| All || 0xFFFFFFF7FFC66000-0xFFFFFFF7FFC6EFFF || 0x80106000 || 0x9000 || 0x6000000000070B || RW- || Kernel .data+.bss
 +
|-
 +
| All || 0xFFFFFFF7FFDC0000-0xFFFFFFF7FFDC0FFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and Reset
 +
|-
 +
| All || 0xFFFFFFF7FFDC2000-0xFFFFFFF7FFDC2FFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1
 +
|-
 +
| All || 0xFFFFFFF7FFDC4000-0xFFFFFFF7FFDC4FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0
 +
|-
 +
| All || 0xFFFFFFF7FFDC6000-0xFFFFFFF7FFDC6FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC
 +
|-
 +
| All || 0xFFFFFFF7FFDC8000-0xFFFFFFF7FFDC8FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A
 +
|-
 +
| All || 0xFFFFFFF7FFDCA000-0xFFFFFFF7FFDCAFFF || 0x80060000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDCE000-0xFFFFFFF7FFDCEFFF || 0x80068000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDD2000-0xFFFFFFF7FFDD2FFF || 0x80070000 || 0x1000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDD4000-0xFFFFFFF7FFDD4FFF || 0x80062000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDD8000-0xFFFFFFF7FFDD8FFF || 0x8006A000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDDC000-0xFFFFFFF7FFDDCFFF || 0x80071000 || 0x1000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDDE000-0xFFFFFFF7FFDDEFFF || 0x80064000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDE2000-0xFFFFFFF7FFDE2FFF || 0x8006C000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDE6000-0xFFFFFFF7FFDE6FFF || 0x80072000 || 0x1000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDE8000-0xFFFFFFF7FFDE8FFF || 0x80066000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDEC000-0xFFFFFFF7FFDECFFF || 0x8006E000 || 0x2000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDF0000-0xFFFFFFF7FFDF0FFF || 0x80073000 || 0x1000 || 0x6000000000070B || RW- ||
 +
|-
 +
| All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor
 +
|-
 +
| All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
 +
|-
 +
| All || 0xFFFFFFF800000000-... || 0x80000000 || ... || 0x60000000000709 || RW- || Raw DRAM access
 +
|}
 +
 
 +
== 3.0.0 ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cores || Virtual || Physical || Size || Attributes || Permissions || Description
 +
|-
 +
| All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC4AFFF || 0x800A0000 || 0x4B000 || 0x78B || R-X || Kernel .text
 +
|-
 +
| All || 0xFFFFFFF7FFC4B000-0xFFFFFFF7FFC4DFFF || 0x800EB000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata
 +
|-
 +
| All || 0xFFFFFFF7FFC4E000-0xFFFFFFF7FFC5AFFF || 0x800EE000 || 0xD000 || 0x6000000000070B || RW- || Kernel .data+.bss
 +
|-
 +
| All || 0xFFFFFFF7FFDAC000-0xFFFFFFF7FFDACFFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and Reset
 +
|-
 +
| All || 0xFFFFFFF7FFDAE000-0xFFFFFFF7FFDAEFFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1
 +
|-
 +
| All || 0xFFFFFFF7FFDB0000-0xFFFFFFF7FFDB0FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0
 +
|-
 +
| All || 0xFFFFFFF7FFDB2000-0xFFFFFFF7FFDB2FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC
 +
|-
 +
| All || 0xFFFFFFF7FFDB4000-0xFFFFFFF7FFDB4FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A
 +
|-
 +
| All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor
 +
|-
 +
| All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
 +
|}
    +
== 4.0.0 ==
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Cores || Virtual || Physical || Size || Attributes || Permissions || Description
! Size
+
|-
! Description
+
| All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC50FFF || 0x800A0000 || 0x51000 || 0x4000000000078B || R-X || Kernel .text
 +
|-
 +
| All || 0xFFFFFFF7FFC51000-0xFFFFFFF7FFC53FFF || 0x800F1000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata
 +
|-
 +
| All || 0xFFFFFFF7FFC54000-0xFFFFFFF7FFC61FFF || 0x800F4000 || 0xE000 || 0x6000000000070B || RW- || Kernel .data+.bss
 +
|-
 +
| All || 0xFFFFFFF7FFDAC000-0xFFFFFFF7FFDACFFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and Reset
 +
|-
 +
| All || 0xFFFFFFF7FFDAE000-0xFFFFFFF7FFDAEFFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1
 +
|-
 +
| All || 0xFFFFFFF7FFDB0000-0xFFFFFFF7FFDB0FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0
 +
|-
 +
| All || 0xFFFFFFF7FFDB2000-0xFFFFFFF7FFDB2FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC
 
|-
 
|-
| 0x0
+
| All || 0xFFFFFFF7FFDB4000-0xFFFFFFF7FFDB4FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A
| 0x100
  −
| [[IPC_Marshalling|IPC]] command buffer
   
|-
 
|-
| 0x100
+
| All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor
| 0xF8
  −
| ?
   
|-
 
|-
| 0x1F8
+
| All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface
| 0x8
  −
| Address of threadctx+0x58.
   
|}
 
|}
   −
==Thread context==
+
The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B.
This is the structure of the 0x228-byte threadctx used by official userland software.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Vmem
! Size
+
! Physmem
! Description
+
|-
 +
| 0xFFFFFFF7FFDF7000
 +
| <physaddr from vmem 0xFFFFFFF7FFDF6000> + 0x1000
 +
|-
 +
| 0xFFFFFFF7FFDF3000
 +
| <physaddr from vmem 0xFFFFFFF7FFDF2000> + 0x1000
 
|-
 
|-
| 0x0
+
| 0xFFFFFFF7FFDF6000
| 0xA8
+
| 0x800XX000
| ?
   
|-
 
|-
| 0xA8
+
| 0xFFFFFFF7FFDF2000
| 0x8
+
| 0x800XX000
| Address of the stack-bottom-mirror which the thread was created with.
   
|-
 
|-
| 0xB0
+
| 0xFFFFFFF7FFDFF000
| 0x8
+
| 0x800XX000
| Size of the stack.
   
|-
 
|-
| 0xB8
+
| 0xFFFFFFF7FFDF9000
| 0x178
+
| 0x800XX000
| ?
   
|}
 
|}
   −
= Kernel =
+
== Notes ==
 +
=== 2.0.0 ===
 
   Granule size for TTBR0*_EL1 is 4KB.
 
   Granule size for TTBR0*_EL1 is 4KB.
 
   TTBR0_EL1 vmem starts at vaddr 0x0.
 
   TTBR0_EL1 vmem starts at vaddr 0x0.
Line 118: Line 334:  
   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.
 
   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).
 
   Hence, for TTBR0, index=((vaddr>>30) & 0x7), and for TTBR1, index=((vaddr>>30) & 0x3f).
  −
As of [[2.0.0]] KASLR is not used.
  −
  −
== [[2.0.0]] ==
      
"Vector Base Address Register (EL1)" = 0xfffffff7ffc50800.
 
"Vector Base Address Register (EL1)" = 0xfffffff7ffc50800.
Line 131: Line 343:     
TTBR1:
 
TTBR1:
* vmem 0xFFFFFFF800000000 is mapped to physmem 0x80000000. Similar to above, except tmp=0 due to wrap-around, etc. The chunksize used when increasing addr is 0xfffffff840000000, with another +=0x40000000 separate from the addr cmp for the loop.
+
* 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>}"
 
** "endaddr = 0x3fffffff + (<size from above> | 0xfffffff800000000); enaddr = (endaddr & 0xffffffffc0000000)-1; if(endaddr >= 0xfffffff800000001){<map mem>}"
   Line 146: Line 358:  
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF800000. physaddr = tablebase + (0x6<<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"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Virtual
+
! Vmem
! Physical
+
! Physmem
 
! Size
 
! Size
! Attributes
+
! Descriptor ORR-value
 
! Permissions
 
! Permissions
 
! Description
 
! Description
 
|-
 
|-
| 0xFFFFFFF800000000-... || 0x80000000 || ... || ? || ? || Raw DRAM access
+
| 0x1F0000000
 +
| 0x50041000
 +
| 0x1000
 +
| 0x40000000000324
 +
|  
 +
| ARM Interrupt Distributor
 
|-
 
|-
| 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC62FFF || 0x800A0000 || 0x63000 || 0x78B || R-X || Kernel .text
+
| 0x1F0002000
 +
| 0x50042000
 +
| 0x1000
 +
| 0x40000000000324
 +
|  
 +
| Interrupt Controller Physical CPU Interface
 
|-
 
|-
| 0xFFFFFFF7FFC63000-0xFFFFFFF7FFC65FFF || 0x80103000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata
+
| 0x1F0005000
 +
| 0x70006000
 +
| 0x1000
 +
| 0x40000000000324
 +
|  
 +
| UART-A
 
|-
 
|-
| 0xFFFFFFF7FFC66000-0xFFFFFFF7FFC6EFFF || 0x80106000 || 0x9000 || 0x6000000000070B || RW- || Kernel .data+.bss
+
| 0x1F0007000
 +
| 0x60006000
 +
| 0x1000
 +
| 0x40000000000324
 +
|  
 +
| Clock and Reset
 
|-
 
|-
| 0xFFFFFFF7FFDCA000-0xFFFFFFF7FFDCAFFF || 0x80060000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0009000
 +
| 0x7000E000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| PMC
 
|-
 
|-
| 0xFFFFFFF7FFDCB000-0xFFFFFFF7FFDCBFFF || 0x80061000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F000B000
 +
| 0x60005000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| TMR
 
|-
 
|-
| 0xFFFFFFF7FFDCE000-0xFFFFFFF7FFDCEFFF || 0x80068000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F000D000
 +
| 0x6000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| System Registers
 
|-
 
|-
| 0xFFFFFFF7FFDD4000-0xFFFFFFF7FFDD4FFF || 0x80062000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F000F000
 +
| 0x70012000
 +
| 0x2000
 +
| 0x40000000000304
 +
|  
 +
| SE
 
|-
 
|-
| 0xFFFFFFF7FFDD5000-0xFFFFFFF7FFDD5FFF || 0x80063000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0012000
 +
| 0x700F0000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| SYSCTR0
 
|-
 
|-
| 0xFFFFFFF7FFDD8000-0xFFFFFFF7FFDD8FFF || 0x8006A000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0014000
 +
| 0x70019000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| MC
 
|-
 
|-
| 0xFFFFFFF7FFDD9000-0xFFFFFFF7FFDD9FFF || 0x8006B000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0016000
 +
| 0x7000F000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| FUSE
 
|-
 
|-
| 0xFFFFFFF7FFDDE000-0xFFFFFFF7FFDDEFFF || 0x80064000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0018000
 +
| 0x70000000
 +
| 0x4000
 +
| 0x40000000000304
 +
|  
 +
| MISC
 
|-
 
|-
| 0xFFFFFFF7FFDDF000-0xFFFFFFF7FFDDFFFF || 0x80065000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F001D000
 +
| 0x60007000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| Flow controller
 
|-
 
|-
| 0xFFFFFFF7FFDE2000-0xFFFFFFF7FFDE2FFF || 0x8006C000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F001F000
 +
| 0x40002000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| IRAM
 
|-
 
|-
| 0xFFFFFFF7FFDE3000-0xFFFFFFF7FFDE3FFF || 0x8006D000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0021000
 +
| 0x7000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| I2C-5
 
|-
 
|-
| 0xFFFFFFF7FFDE8000-0xFFFFFFF7FFDE8FFF || 0x80066000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0023000
 +
| 0x6000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| GPIO-1
 
|-
 
|-
| 0xFFFFFFF7FFDE9000-0xFFFFFFF7FFDE9FFF || 0x80067000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0025000
 +
| 0x7000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| I2C
 
|-
 
|-
| 0xFFFFFFF7FFDCF000-0xFFFFFFF7FFDCFFFF || 0x80069000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F0180000
 +
| 0x40020000
 +
| 0x10000
 +
| 0x40000000000324
 +
|  
 +
| IRAM
 
|-
 
|-
| 0xFFFFFFF7FFDEC000-0xFFFFFFF7FFDECFFF || 0x8006E000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01A0000
 +
| 0x7C010000
 +
| 0x10000
 +
| 0x40000000000384
 +
|  
 +
| TZRAM
 
|-
 
|-
| 0xFFFFFFF7FFDED000-0xFFFFFFF7FFDEDFFF || 0x8006F000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01C3000
 +
| 0x80010000
 +
| 0x10000
 +
| 0x40000000000324
 +
|  
 +
| EMEM
 
|-
 
|-
| 0xFFFFFFF7FFDD2000-0xFFFFFFF7FFDD2FFF || 0x80070000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01C2000
 +
| 0x8000F000
 +
| 0x1000
 +
| 0x40000000000324
 +
|  
 +
| EMEM
 
|-
 
|-
| 0xFFFFFFF7FFDDC000-0xFFFFFFF7FFDDCFFF || 0x80071000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01E0000
 +
| 0x7C013000
 +
| 0xB000
 +
| 0x304
 +
|  
 +
| TZRAM (Secure Monitor)
 
|-
 
|-
| 0xFFFFFFF7FFDE6000-0xFFFFFFF7FFDE6FFF || 0x80072000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01F0000
 +
| 0x7C01E000
 +
| 0x2000
 +
| 0x304
 +
|  
 +
| TZRAM (Secure Monitor and ARMv8 init)
 
|-
 
|-
| 0xFFFFFFF7FFDF0000-0xFFFFFFF7FFDF0FFF || 0x80073000 || 0x1000 || 0x6000000000070B || RW- ||
+
| 0x1F01F6000
 +
| 0x7C01E000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| TZRAM
 
|-
 
|-
| 0xFFFFFFF7FFDC6000-0xFFFFFFF7FFDC6FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC IO
+
| 0x1F01F8000
 +
| 0x7C01F000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| TZRAM
 
|-
 
|-
| 0xFFFFFFF7FFDC4000-0xFFFFFFF7FFDC4FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0 IO
+
| 0x1F01FA000
 +
| 0x7C010000
 +
| 0x1000
 +
| 0x304
 +
|  
 +
| TZRAM (Secure Monitor exception vectors)
 
|-
 
|-
| 0xFFFFFFF7FFDC2000-0xFFFFFFF7FFDC2FFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1 IO
+
| 0x1F01FC000
 +
| 0x7C011000
 +
| 0x1000
 +
| 0x40000000000304
 +
|  
 +
| TZRAM
 
|-
 
|-
| 0xFFFFFFF7FFDC0000-0xFFFFFFF7FFDC0FFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || CLK IO
+
| 0x1F01FE000
|-
+
| 0x7C012000
| 0xFFFFFFF7FFDC8000-0xFFFFFFF7FFDC8FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A IO
+
| 0x1000
|-
+
| 0x40000000000304
| 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Distributor IO
+
|  
|-
+
| TZRAM
| 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller IO
   
|}
 
|}
  −
The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B.
  −
  −
{| class="wikitable" border="1"
  −
|-
  −
! Vmem
  −
! Physmem
  −
|-
  −
| 0xFFFFFFF7FFDF7000
  −
| <physaddr from vmem 0xFFFFFFF7FFDF6000> + 0x1000
  −
|-
  −
| 0xFFFFFFF7FFDF3000
  −
| <physaddr from vmem 0xFFFFFFF7FFDF2000> + 0x1000
  −
|-
  −
| 0xFFFFFFF7FFDF6000
  −
| 0x800XX000
  −
|-
  −
| 0xFFFFFFF7FFDF2000
  −
| 0x800XX000
  −
|-
  −
| 0xFFFFFFF7FFDFF000
  −
| 0x800XX000
  −
|-
  −
| 0xFFFFFFF7FFDF9000
  −
| 0x800XX000
  −
|}
  −
  −
= Secure Monitor =
      
== [[2.0.0]] ==
 
== [[2.0.0]] ==
Line 304: Line 626:  
| 0x40000000000304
 
| 0x40000000000304
 
|  
 
|  
| RTC
+
| PMC
 
|-
 
|-
 
| 0x1F008B000
 
| 0x1F008B000
Line 444: Line 766:  
| 0x300
 
| 0x300
 
|  
 
|  
| TZRAM (Secure Monitor init)
+
| TZRAM (Secure Monitor and ARMv8 init)
 +
|-
 +
| 0x1F01F4000
 +
| <varies>
 +
| 0x1000
 +
| 0x40000000000320
 +
|
 +
| DRAM (SPL .bss buffer visible to the Security Engine)
 
|-
 
|-
 
| 0x1F01F6000
 
| 0x1F01F6000
Line 481: Line 810:  
| TZRAM
 
| TZRAM
 
|}
 
|}
 +
 +
== [[5.0.0]] ==
 +
5.0.0 modified the address map to have separate .text, .rodata, and .rwdata segments, instead of a single RWX segment.
 +
 +
However, the .rodata and .rwdata segments are both (mistakenly?) mapped R-W.
 +
 +
Because the same L3 page is shared for all mappings, this required modifying segment layout significantly to prevent clashes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Vmem
 +
! Physmem
 +
! Size
 +
! Descriptor ORR-value
 +
! Description
 +
|-
 +
| 0x7C010000
 +
| 0x7C010000
 +
| 0x10000
 +
| 0x300
 +
| TZRAM Identity RWX (for init)
 +
|-
 +
| 0x40020000
 +
| 0x40020000
 +
| 0x20000
 +
| 0x300
 +
| IRAM Identity RWX (for init)
 +
|-
 +
| 0x1F0080000
 +
| 0x50041000
 +
| 0x1000
 +
| 0x40000000000304
 +
| ARM Interrupt Distributor
 +
|-
 +
| 0x1F0082000
 +
| 0x50042000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Interrupt Controller Physical CPU
 +
|-
 +
| 0x1F0085000
 +
| 0x70006000
 +
| 0x1000
 +
| 0x40000000000324
 +
| UART-A
 +
|-
 +
| 0x1F0087000
 +
| 0x60006000
 +
| 0x1000
 +
| 0x40000000000324
 +
| Clock and Reset
 +
|-
 +
| 0x1F0089000
 +
| 0x7000E000
 +
| 0x1000
 +
| 0x40000000000304
 +
| PMC
 +
|-
 +
| 0x1F008B000
 +
| 0x60005000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Timers
 +
|-
 +
| 0x1F008D000
 +
| 0x6000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| System Registers
 +
|-
 +
| 0x1F008F000
 +
| 0x70012000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Security Engine
 +
|-
 +
| 0x1F00AD000
 +
| 0x70412000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Erista: Nothing Present, Mariko: Security Engine 2
 +
|-
 +
| 0x1F0092000
 +
| 0x700F0000
 +
| 0x1000
 +
| 0x40000000000304
 +
| SYSCTR0
 +
|-
 +
| 0x1F0094000
 +
| 0x70019000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Memory Controller
 +
|-
 +
| 0x1F0096000
 +
| 0x7000F000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Fuse Registers
 +
|-
 +
| 0x1F0098000
 +
| 0x70000000
 +
| 0x4000
 +
| 0x40000000000304
 +
| MISC Registers
 +
|-
 +
| 0x1F009D000
 +
| 0x60007000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Flow Controller
 +
|-
 +
| 0x1F009F000
 +
| 0x40002000
 +
| 0x1000
 +
| 0x40000000000304
 +
| IRAM
 +
|-
 +
| 0x1F00A1000
 +
| 0x7000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| I2C-5
 +
|-
 +
| 0x1F00A3000
 +
| 0x6000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| GPIO-1
 +
|-
 +
| 0x1F00A5000
 +
| 0x7000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| I2C
 +
|-
 +
| 0x1F00A7000
 +
| 0x6000F000
 +
| 0x1000
 +
| 0x40000000000304
 +
| BPMP Exception Vectors
 +
|-
 +
| 0x1F00A9000
 +
| 0x7001C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| MC0
 +
|-
 +
| 0x1F00AB000
 +
| 0x7001D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| MC1
 +
|-
 +
| 0x1F0100000
 +
| 0x7C010000
 +
| 0x10000
 +
| 0x40000000000380
 +
| TZRAM (R-- for context save)
 +
|-
 +
| 0x1F0140000
 +
| 0x7C012000
 +
| 0x9000
 +
| 0x300
 +
| TZRAM (R-X .text)
 +
|-
 +
| 0x1F0149000
 +
| 0x7C01B000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (RW- .rodata)
 +
|-
 +
| 0x1F014A000
 +
| 0x7C01C000
 +
| 0x2000
 +
| 0x40000000000300
 +
| TZRAM (RW- .rwdata)
 +
|-
 +
| 0x1F01A0000
 +
| 0x40020000
 +
| 0x10000
 +
| 0x40000000000324
 +
| IRAM (RW- for context save)
 +
|-
 +
| 0x1F01B0000
 +
| 0x40003000
 +
| 0x1000
 +
| 0x40000000000324
 +
| IRAM (BPMP firmware destination)
 +
|-
 +
| 0x1F01C7000
 +
| 0x8000F000
 +
| 0x1000
 +
| 0x40000000000324
 +
| DRAM (SE Context Save destination)
 +
|-
 +
| 0x1F01E0000
 +
| 0x7C010000
 +
| 0x2000
 +
| 0x300
 +
| TZRAM (RWX pk2ldr for init)
 +
|-
 +
| 0x1F01F4000
 +
| X
 +
| 0x1000
 +
| 0x40000000000723
 +
| DRAM (SPL .bss buffer visible to the Security Engine)
 +
|-
 +
| 0x1F01F6000
 +
| 0x7C010000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks)
 +
|-
 +
| 0x1F01F8000
 +
| 0x7C011000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks)
 +
|-
 +
| 0x1F01FA000
 +
| 0x7C01D000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks, warmboot crt0)
 +
|-
 +
| 0x1F01FC000
 +
| 0x7C01E000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (L2 Page Table)
 +
|-
 +
| 0x1F01FE000
 +
| 0x7C01F000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (L3 Page Table)
 +
|}
 +
 +
== [[6.0.0]] ==
 +
6.0.0 reduced the .rwdata segment to one page (previously 2).
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Vmem
 +
! Physmem
 +
! Size
 +
! Descriptor ORR-value
 +
! Description
 +
|-
 +
| 0x7C010000
 +
| 0x7C010000
 +
| 0x10000
 +
| 0x300
 +
| TZRAM Identity RWX (for init)
 +
|-
 +
| 0x40020000
 +
| 0x40020000
 +
| 0x20000
 +
| 0x300
 +
| IRAM Identity RWX (for init)
 +
|-
 +
| 0x1F0080000
 +
| 0x50041000
 +
| 0x1000
 +
| 0x40000000000304
 +
| ARM Interrupt Distributor
 +
|-
 +
| 0x1F0082000
 +
| 0x50042000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Interrupt Controller Physical CPU
 +
|-
 +
| 0x1F0085000
 +
| 0x70006000
 +
| 0x1000
 +
| 0x40000000000324
 +
| UART-A
 +
|-
 +
| 0x1F0087000
 +
| 0x60006000
 +
| 0x1000
 +
| 0x40000000000324
 +
| Clock and Reset
 +
|-
 +
| 0x1F0089000
 +
| 0x7000E000
 +
| 0x1000
 +
| 0x40000000000304
 +
| PMC
 +
|-
 +
| 0x1F008B000
 +
| 0x60005000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Timers
 +
|-
 +
| 0x1F008D000
 +
| 0x6000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| System Registers
 +
|-
 +
| 0x1F008F000
 +
| 0x70012000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Security Engine
 +
|-
 +
| 0x1F00AD000
 +
| 0x70412000
 +
| 0x2000
 +
| 0x40000000000304
 +
| Erista: Nothing Present, Mariko: Security Engine 2
 +
|-
 +
| 0x1F0092000
 +
| 0x700F0000
 +
| 0x1000
 +
| 0x40000000000304
 +
| SYSCTR0
 +
|-
 +
| 0x1F0094000
 +
| 0x70019000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Memory Controller
 +
|-
 +
| 0x1F0096000
 +
| 0x7000F000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Fuse Registers
 +
|-
 +
| 0x1F0098000
 +
| 0x70000000
 +
| 0x4000
 +
| 0x40000000000304
 +
| MISC Registers
 +
|-
 +
| 0x1F009D000
 +
| 0x60007000
 +
| 0x1000
 +
| 0x40000000000304
 +
| Flow Controller
 +
|-
 +
| 0x1F009F000
 +
| 0x40002000
 +
| 0x1000
 +
| 0x40000000000304
 +
| IRAM
 +
|-
 +
| 0x1F00A1000
 +
| 0x7000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| I2C-5
 +
|-
 +
| 0x1F00A3000
 +
| 0x6000D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| GPIO-1
 +
|-
 +
| 0x1F00A5000
 +
| 0x7000C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| I2C
 +
|-
 +
| 0x1F00A7000
 +
| 0x6000F000
 +
| 0x1000
 +
| 0x40000000000304
 +
| BPMP Exception Vectors
 +
|-
 +
| 0x1F00A9000
 +
| 0x7001C000
 +
| 0x1000
 +
| 0x40000000000304
 +
| MC0
 +
|-
 +
| 0x1F00AB000
 +
| 0x7001D000
 +
| 0x1000
 +
| 0x40000000000304
 +
| MC1
 +
|-
 +
| 0x1F0100000
 +
| 0x7C010000
 +
| 0x10000
 +
| 0x40000000000380
 +
| TZRAM (R-- for context save)
 +
|-
 +
| 0x1F0140000
 +
| 0x7C012000
 +
| 0x9000
 +
| 0x300
 +
| TZRAM (R-X .text)
 +
|-
 +
| 0x1F0149000
 +
| 0x7C01B000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (RW- .rodata)
 +
|-
 +
| 0x1F014A000
 +
| 0x7C01C000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (RW- .rwdata)
 +
|-
 +
| 0x1F01A0000
 +
| 0x40020000
 +
| 0x10000
 +
| 0x40000000000324
 +
| IRAM (RW- for context save)
 +
|-
 +
| 0x1F01B0000
 +
| 0x40003000
 +
| 0x1000
 +
| 0x40000000000324
 +
| IRAM (BPMP firmware destination)
 +
|-
 +
| 0x1F01C7000
 +
| 0x8000F000
 +
| 0x1000
 +
| 0x40000000000324
 +
| DRAM (SE Context Save destination)
 +
|-
 +
| 0x1F01E0000
 +
| 0x7C010000
 +
| 0x2000
 +
| 0x300
 +
| TZRAM (RWX pk2ldr for init)
 +
|-
 +
| 0x1F01F4000
 +
| X
 +
| 0x1000
 +
| 0x40000000000723
 +
| DRAM (SPL .bss buffer visible to the Security Engine)
 +
|-
 +
| 0x1F01F6000
 +
| 0x7C010000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks)
 +
|-
 +
| 0x1F01F8000
 +
| 0x7C011000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks)
 +
|-
 +
| 0x1F01FA000
 +
| 0x7C01D000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (stacks, warmboot crt0)
 +
|-
 +
| 0x1F01FC000
 +
| 0x7C01E000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (L2 Page Table)
 +
|-
 +
| 0x1F01FE000
 +
| 0x7C01F000
 +
| 0x1000
 +
| 0x40000000000300
 +
| TZRAM (L3 Page Table)
 +
|}
 +
 +
= IRAM =
 +
== BIT ==
 +
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"
 +
|-
 +
!  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*0x04
 +
|  BootTimeLog
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x04
 +
|  BootTimeLogInit
 +
|-
 +
|  0x04
 +
|  0x04
 +
|  BootTimeLogExit
 +
|-
 +
|  0x08
 +
|  0x04
 +
|  BootReadBctTickCnt
 +
|-
 +
|  0x0C
 +
|  0x04
 +
|  BootReadBLTickCnt
 +
|}
 +
|-
 +
|  0x28
 +
|  0x04
 +
|  OscFrequency
 +
|  Value from CLK_RST_CONTROLLER_OSC_CTRL.
 +
|-
 +
|  0x2C
 +
|  0x01
 +
|  DevInitialized
 +
|  Set to 1 after the boot device is initialized.
 +
|-
 +
|  0x2D
 +
|  0x01
 +
|  SdramInitialized
 +
|  Set to 1 after the SDRAM parameters are parsed.
 +
|-
 +
|  0x2E
 +
|  0x01
 +
|  ClearedForceRecovery
 +
|  Set to 1 if bit 2 was set in APBDEV_PMC_SCRATCH0.
 +
|-
 +
|  0x2F
 +
|  0x01
 +
|  ClearedFailBack
 +
|  Set to 1 if bit 4 was set in APBDEV_PMC_SCRATCH0.
 +
|-
 +
|  0x30
 +
|  0x01
 +
|  InvokedFailBack
 +
|  Set to 1 if the bootloaders have different versions in the BCT.
 +
|-
 +
|  0x31
 +
|  0x01
 +
|  IRomPatchStatus
 +
 +
|-
 +
|  0x32
 +
|  0x01
 +
|  BctValid
 +
|  Set to 1 if the BCT was parsed successfully.
 +
|-
 +
|  0x33
 +
|  0x09
 +
|  BctStatus
 +
|  Each bit contains the status for BCT reads in a given block.
 +
|-
 +
|  0x3C
 +
|  0x04
 +
|  BctLastJournalRead
 +
|  Contains the status of the last journal block read.
 +
None = 0
 +
Success = 1
 +
ValidationFailure = 2
 +
DeviceReadError = 3
 +
|-
 +
|  0x40
 +
|  0x04
 +
|  BctBlock
 +
|  Block number where the BCT was found.
 +
|-
 +
|  0x44
 +
|  0x04
 +
|  BctPage
 +
|  Page number where the BCT was found.
 +
|-
 +
|  0x48
 +
|  0x04
 +
|  BctSize
 +
|  Size of the BCT in IRAM (0x2800).
 +
|-
 +
|  0x4C
 +
|  0x04
 +
|  BctPtr
 +
|  Pointer to the BCT in IRAM (0x40000100).
 +
|-
 +
|  0x50
 +
|  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
 +
|}
 +
|-
 +
|  0xB0
 +
|  0x3C
 +
|  SecondaryDevStatus
 +
|  Structure to hold secondary boot device status.
 +
For SDMMC, the following applies:
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Field
 +
|-
 +
|  0x00
 +
|  0x01
 +
|  FuseDataWidth
 +
|-
 +
|  0x01
 +
|  0x01
 +
|  FuseVoltageRange
 +
|-
 +
|  0x02
 +
|  0x01
 +
|  FuseDisableBootMode
 +
|-
 +
|  0x03
 +
|  0x01
 +
|  FuseDdrMode
 +
|-
 +
|  0x04
 +
|  0x01
 +
|  DiscoveredCardType
 +
|-
 +
|  0x05
 +
|  0x03
 +
|  Reserved
 +
|-
 +
|  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>
 +
 +
Then further configured using [[SMC#ConfigureCarveout|smcConfigureCarveout]].
 +
 +
=== GSC5 ===
 +
This carveout is, by default, for TSECB. In the Switch's case, this carveout is used by the Kernel.
 +
 +
It is initially configured as follows:
 +
<pre>
 +
*(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>
 +
 +
Then further configured using [[SMC#ConfigureCarveout|smcConfigureCarveout]].

Navigation menu