Changes

2,275 bytes added ,  00:19, 25 November 2018
no edit summary
Line 5: Line 5:     
== Registers ==
 
== Registers ==
Registers from 0x54500000 to 0x54501000 are used to configure values for the host interface (HOST1X).
+
Registers from 0x54500000 to 0x54501000 are used to configure the host interface (HOST1X).
   −
Registers from 0x54501000 to 0x54502000 are a MMIO window for communicating with the Falcon microprocessor. From this range, the subset of registers from 0x54501400 to 0x54501FE8 are specific to the TSEC.
+
Registers from 0x54501000 to 0x54502000 are a MMIO window for communicating with the Falcon microprocessor. From this range, the subset of registers from 0x54501400 to 0x54501FE8 are specific to the TSEC and are subdivided into:
 +
* 0x54501400 to 0x54501500: SCP (secure crypto processor?).
 +
* 0x54501500 to 0x54501600: Unknown.
 +
* 0x54501600 to 0x54501700: MCCIF (Memory Controller Client Interface).
 +
* 0x54501700 to 0x54501800: DMA.
 +
* 0x54501800 to 0x54501900: TEGRA (miscellaneous interfaces).  
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 80: Line 85:  
| [[#FALCON_IRQDEST|FALCON_IRQDEST]]
 
| [[#FALCON_IRQDEST|FALCON_IRQDEST]]
 
| 0x5450101C
 
| 0x5450101C
 +
| 0x04
 +
|-
 +
| FALCON_PERIODIC_PERIOD
 +
| 0x54501020
 +
| 0x04
 +
|-
 +
| FALCON_PERIODIC_TIME
 +
| 0x54501024
 +
| 0x04
 +
|-
 +
| FALCON_PERIODIC_ENABLE
 +
| 0x54501028
 +
| 0x04
 +
|-
 +
| FALCON_TIME_LOW
 +
| 0x5450102C
 +
| 0x04
 +
|-
 +
| FALCON_TIME_HIGH
 +
| 0x54501030
 +
| 0x04
 +
|-
 +
| FALCON_WATCHDOG_TIME
 +
| 0x54501034
 +
| 0x04
 +
|-
 +
| FALCON_WATCHDOG_ENABLE
 +
| 0x54501038
 
| 0x04
 
| 0x04
 
|-
 
|-
Line 106: Line 139:  
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_SCRATCH2
+
| FALCON_CMDCTX
| 0x54501080
+
| 0x54501058
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_SCRATCH3
+
| FALCON_STATUS_MASK
| 0x54501084
+
| 0x5450105C
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_CGCTL
+
| FALCON_VM_SUPERVISOR
| 0x545010A0
+
| 0x54501060
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_ENGCTL
+
| FALCON_FIFO_DATA
| 0x545010A4
+
| 0x54501064
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_CPUCTL|FALCON_CPUCTL]]
+
| FALCON_FIFO_CMD
| 0x54501100
+
| 0x54501068
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_BOOTVEC|FALCON_BOOTVEC]]
+
| FALCON_FIFO_DATA_WR
| 0x54501104
+
| 0x5450106C
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_HWCFG
+
| FALCON_FIFO_OCCUPIED
| 0x54501108
+
| 0x54501070
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_DMACTL|FALCON_DMACTL]]
+
| FALCON_FIFO_ACK
| 0x5450110C
+
| 0x54501074
 +
| 0x04
 +
|-
 +
| FALCON_FIFO_LIMIT
 +
| 0x54501078
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_DMATRFBASE|FALCON_DMATRFBASE]]
+
| FALCON_SUBENGINE_RESET
| 0x54501110
+
| 0x5450107C
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_DMATRFMOFFS|FALCON_DMATRFMOFFS]]
+
| FALCON_SCRATCH2
| 0x54501114
+
| 0x54501080
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_DMATRFCMD|FALCON_DMATRFCMD]]
+
| FALCON_SCRATCH3
| 0x54501118
+
| 0x54501084
 
| 0x04
 
| 0x04
 
|-
 
|-
| [[#FALCON_DMATRFFBOFFS|FALCON_DMATRFFBOFFS]]
+
| FALCON_PM_TRIGGER
| 0x5450111C
+
| 0x54501088
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_CPUCTL_ALIAS
+
| FALCON_PM_MODE
| 0x54501130
+
| 0x5450108C
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_IMFILLRNG1
+
| FALCON_DEBUG1
| 0x54501154
+
| 0x54501090
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_IMFILLCTL
+
| FALCON_DEBUGINFO
| 0x54501158
+
| 0x54501094
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_EXTERRADDR
+
| FALCON_BREAKPOINT0
| 0x54501168
+
| 0x54501098
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_EXTERRSTAT
+
| FALCON_BREAKPOINT1
| 0x5450116C
+
| 0x5450109C
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_CG2
+
| FALCON_CGCTL
| 0x5450117C
+
| 0x545010A0
 
| 0x04
 
| 0x04
 
|-
 
|-
| FALCON_CODE_INDEX
+
| FALCON_ENGCTL
| 0x54501180
+
| 0x545010A4
| 0x04
+
| 0x04
|-
+
|-
| FALCON_CODE
+
| FALCON_PM_SEL
| 0x54501184
+
| 0x545010A8
| 0x04
+
| 0x04
|-
+
|-
| FALCON_CODE_VIRT_ADDR
+
| FALCON_HOST_IO_INDEX
| 0x54501188
+
| 0x545010AC
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA_INDEX0
+
| [[#FALCON_CPUCTL|FALCON_CPUCTL]]
| 0x545011C0
+
| 0x54501100
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA0
+
| [[#FALCON_BOOTVEC|FALCON_BOOTVEC]]
| 0x545011C4
+
| 0x54501104
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA_INDEX1
+
| FALCON_HWCFG
| 0x545011C8
+
| 0x54501108
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA1
+
| [[#FALCON_DMACTL|FALCON_DMACTL]]
| 0x545011CC
+
| 0x5450110C
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA_INDEX2
+
| [[#FALCON_DMATRFBASE|FALCON_DMATRFBASE]]
| 0x545011D0
+
| 0x54501110
| 0x04
+
| 0x04
|-
+
|-
| FALCON_DATA2
+
| [[#FALCON_DMATRFMOFFS|FALCON_DMATRFMOFFS]]
 +
| 0x54501114
 +
| 0x04
 +
|-
 +
| [[#FALCON_DMATRFCMD|FALCON_DMATRFCMD]]
 +
| 0x54501118
 +
| 0x04
 +
|-
 +
| [[#FALCON_DMATRFFBOFFS|FALCON_DMATRFFBOFFS]]
 +
| 0x5450111C
 +
| 0x04
 +
|-
 +
| FALCON_DMATRFSTAT
 +
| 0x54501120
 +
| 0x04
 +
|-
 +
| FALCON_CRYPTTRFSTAT
 +
| 0x54501124
 +
| 0x04
 +
|-
 +
| FALCON_CPUSTAT
 +
| 0x54501128
 +
| 0x04
 +
|-
 +
| FALCON_HWCFG_ALIAS
 +
| 0x5450112C
 +
| 0x04
 +
|-
 +
| FALCON_CPUCTL_ALIAS
 +
| 0x54501130
 +
| 0x04
 +
|-
 +
| FALCON_TLB_CMD
 +
| 0x54501140
 +
| 0x04
 +
|-
 +
| FALCON_TLB_CMD_RES
 +
| 0x54501144
 +
| 0x04
 +
|-
 +
| FALCON_BRANCH_HISTORY_CTRL
 +
| 0x54501148
 +
| 0x04
 +
|-
 +
| FALCON_BRANCH_HISTORY_PC
 +
| 0x5450114C
 +
| 0x04
 +
|-
 +
| FALCON_IMFILLRNG0
 +
| 0x54501150
 +
| 0x04
 +
|-
 +
| FALCON_IMFILLRNG1
 +
| 0x54501154
 +
| 0x04
 +
|-
 +
| FALCON_IMFILLCTL
 +
| 0x54501158
 +
| 0x04
 +
|-
 +
| FALCON_EXTERRWIN
 +
| 0x54501160
 +
| 0x04
 +
|-
 +
| FALCON_EXTERRCFG
 +
| 0x54501164
 +
| 0x04
 +
|-
 +
| FALCON_EXTERRADDR
 +
| 0x54501168
 +
| 0x04
 +
|-
 +
| FALCON_EXTERRSTAT
 +
| 0x5450116C
 +
| 0x04
 +
|-
 +
| FALCON_CG2
 +
| 0x5450117C
 +
| 0x04
 +
|-
 +
| FALCON_CODE_INDEX
 +
| 0x54501180
 +
| 0x04
 +
|-
 +
| FALCON_CODE
 +
| 0x54501184
 +
| 0x04
 +
|-
 +
| FALCON_CODE_VIRT_ADDR
 +
| 0x54501188
 +
| 0x04
 +
|-
 +
| FALCON_DATA_INDEX0
 +
| 0x545011C0
 +
| 0x04
 +
|-
 +
| FALCON_DATA0
 +
| 0x545011C4
 +
| 0x04
 +
|-
 +
| FALCON_DATA_INDEX1
 +
| 0x545011C8
 +
| 0x04
 +
|-
 +
| FALCON_DATA1
 +
| 0x545011CC
 +
| 0x04
 +
|-
 +
| FALCON_DATA_INDEX2
 +
| 0x545011D0
 +
| 0x04
 +
|-
 +
| FALCON_DATA2
 
| 0x545011D4
 
| 0x545011D4
 
| 0x04
 
| 0x04
Line 274: Line 423:  
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK0
+
| TSEC_SCP_UNK0
 
| 0x54501400
 
| 0x54501400
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK1
+
| TSEC_SCP_UNK1
 
| 0x54501404
 
| 0x54501404
 
| 0x04
 
| 0x04
Line 290: Line 439:  
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK2
+
| TSEC_SCP_UNK2
 
| 0x54501410
 
| 0x54501410
 
| 0x04
 
| 0x04
Line 298: Line 447:  
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK3
+
| TSEC_SCP_UNK3
 
| 0x54501420
 
| 0x54501420
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK4
+
| TSEC_SCP_UNK4
 
| 0x54501428
 
| 0x54501428
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_CTL_UNK5
+
| TSEC_SCP_UNK5
 
| 0x54501430
 
| 0x54501430
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_UNK0
+
| TSEC_SCP_UNK6
 
| 0x54501454
 
| 0x54501454
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_UNK1
+
| TSEC_SCP_UNK7
 
| 0x54501458
 
| 0x54501458
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_UNK2
+
| TSEC_SCP_UNK8
 
| 0x54501470
 
| 0x54501470
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_UNK3
+
| TSEC_SCP_UNK9
 
| 0x54501480
 
| 0x54501480
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_SCP_UNK4
+
| TSEC_SCP_UNK10
 
| 0x54501490
 
| 0x54501490
 
| 0x04
 
| 0x04
Line 366: Line 515:  
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_MCCIF_UNK0
+
| TSEC_MCCIF_UNK0
 
| 0x54501600
 
| 0x54501600
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_MCCIF_FIFOCTRL
+
| TSEC_MCCIF_FIFOCTRL
 
| 0x54501604
 
| 0x54501604
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_MCCIF_UNK1
+
| TSEC_MCCIF_UNK1
 
| 0x54501608
 
| 0x54501608
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_MCCIF_UNK2
+
| TSEC_MCCIF_UNK2
 
| 0x5450160C
 
| 0x5450160C
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_UNK0
+
| TSEC_MCCIF_UNK3
 
| 0x54501630
 
| 0x54501630
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_UNK1
+
| TSEC_MCCIF_UNK4
 
| 0x54501634
 
| 0x54501634
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_UNK2
+
| TSEC_MCCIF_UNK5
 
| 0x54501640
 
| 0x54501640
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_UNK3
+
| [[#TSEC_MCCIF_UNK6|TSEC_MCCIF_UNK6]]
 
| 0x54501644
 
| 0x54501644
 
| 0x04
 
| 0x04
 
|-
 
|-
| TSEC_TFBIF_UNK4
+
| [[#TSEC_MCCIF_UNK7|TSEC_MCCIF_UNK7]]
 
| 0x54501648
 
| 0x54501648
 
| 0x04
 
| 0x04
Line 586: Line 735:  
| TSEC_SCP_CTL_PKEY_LOADED
 
| TSEC_SCP_CTL_PKEY_LOADED
 
|}
 
|}
 +
 +
=== TSEC_MCCIF_UNK6 ===
 +
Used to control accesses to DRAM.
 +
 +
[6.0.0+] The nvhost_tsec firmware sets this register to 0x10 or 0x111110 before reading memory from the GPU UCODE carveout.
 +
 +
=== TSEC_MCCIF_UNK7 ===
 +
Used to control accesses to DRAM.
 +
 +
[6.0.0+] The nvhost_tsec firmware sets this register to (data_size << 4) before reading memory from the GPU UCODE carveout.
    
=== TSEC_DMA_CMD ===
 
=== TSEC_DMA_CMD ===
Line 792: Line 951:  
  deadlock();
 
  deadlock();
   −
== Device key generation ==
+
== TSEC key generation ==
The TSEC device key is generated by reading SOR1 registers modified by the Falcon CPU.
+
The TSEC key is generated by reading SOR1 registers modified by the Falcon CPU.
 
  // Clear magic value in host1x scratch space
 
  // Clear magic value in host1x scratch space
 
  *(u32 *)0x50003300 = 0;
 
  *(u32 *)0x50003300 = 0;
 
   
 
   
  // Read TSEC device key
+
  // Read TSEC key
  u32 tsec_device_key[4];  
+
  u32 tsec_key[4];  
  tsec_device_key[0] = *(u32 *)NV_SOR_DP_HDCP_BKSV_LSB;
+
  tsec_key[0] = *(u32 *)NV_SOR_DP_HDCP_BKSV_LSB;
  tsec_device_key[1] = *(u32 *)NV_SOR_TMDS_HDCP_BKSV_LSB;
+
  tsec_key[1] = *(u32 *)NV_SOR_TMDS_HDCP_BKSV_LSB;
  tsec_device_key[2] = *(u32 *)NV_SOR_TMDS_HDCP_CN_MSB;
+
  tsec_key[2] = *(u32 *)NV_SOR_TMDS_HDCP_CN_MSB;
  tsec_device_key[3] = *(u32 *)NV_SOR_TMDS_HDCP_CN_LSB;
+
  tsec_key[3] = *(u32 *)NV_SOR_TMDS_HDCP_CN_LSB;
 
   
 
   
 
  // Clear SOR1 registers
 
  // Clear SOR1 registers
Line 813: Line 972:  
     out_size = 0x10;
 
     out_size = 0x10;
 
   
 
   
  // Copy back the TSEC device key
+
  // Copy back the TSEC key
  memcpy(out_buf, tsec_device_key, out_size);
+
  memcpy(out_buf, tsec_key, out_size);
    
[6.2.0+] This is now done inside an encrypted TSEC payload.
 
[6.2.0+] This is now done inside an encrypted TSEC payload.
Line 860: Line 1,019:  
== Boot ==
 
== Boot ==
 
During this stage, [[#Key data|key data]] is loaded and [[#KeygenLdr|KeygenLdr]] is authenticated, loaded and executed.
 
During this stage, [[#Key data|key data]] is loaded and [[#KeygenLdr|KeygenLdr]] is authenticated, loaded and executed.
Before returning, this stage writes back to the host (using MMIO registers) and sets the device key used by the first bootloader.
+
Before returning, this stage writes back to the host (using MMIO registers) and sets the key used by the first bootloader.
    
[6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#Loader|Loader]].
 
[6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#Loader|Loader]].
Line 876: Line 1,035:     
=== Main ===
 
=== Main ===
Falcon reads the [[#Key data|key data]], authenticates, loads and executes [[#KeygenLdr|KeygenLdr]] and finally sets the device key.
+
Falcon reads the [[#Key data|key data]] and then authenticates, loads and executes [[#KeygenLdr|KeygenLdr]] which sets the TSEC key.
 
  u32 boot_base_addr = 0;
 
  u32 boot_base_addr = 0;
 
  u8 key_data_buf[0x7C];
 
  u8 key_data_buf[0x7C];
Line 972: Line 1,131:  
  }
 
  }
 
   
 
   
  // Write TSEC device key to registers
+
  // Overwrite the TSEC key in SOR1 registers
  set_device_key(key_data_buf);
+
  // This has no effect because the KeygenLdr locks out the TSEC DMA engine
 +
tsec_set_key(key_data_buf);
 
   
 
   
 
  return boot_res;
 
  return boot_res;
Line 997: Line 1,157:  
  return 0;
 
  return 0;
   −
==== set_device_key ====
+
==== tsec_set_key ====
This method takes '''key_data_buf''' as argument and writes the TSEC key to SOR1 registers.
+
This method takes '''key_data_buf''' (a 16 bytes buffer) as argument and writes its contents to SOR1 registers.
 
  // This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40)
 
  // This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40)
 
  *(u32 *)TSEC_DMA_UNK = 0xFFF;
 
  *(u32 *)TSEC_DMA_UNK = 0xFFF;
Line 1,270: Line 1,430:  
  else if (key_version == 0x02)         // Use HOVI_COMMON_01
 
  else if (key_version == 0x02)         // Use HOVI_COMMON_01
 
   hovi_key_addr = key_buf + 0x60;
 
   hovi_key_addr = key_buf + 0x60;
  else if (key_version == 0x03)         // Use empty key
+
  else if (key_version == 0x03)         // Use debug key (empty)
 
   hovi_key_addr = key_buf + 0x00;
 
   hovi_key_addr = key_buf + 0x00;
 
  else
 
  else
Line 1,560: Line 1,720:     
== Keygen ==
 
== Keygen ==
This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC device key.
+
This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC key.
    
== Loader ==
 
== Loader ==
 
This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions).
 
This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions).
After the TSEC device key has been generated, execution returns to this stage which then parses and executes [[#Payload|Payload]].
+
After the TSEC key has been generated, execution returns to this stage which then parses and executes [[#Payload|Payload]].
    
=== Main ===
 
=== Main ===
Line 1,774: Line 1,934:  
   
 
   
 
  // fuc5 crypt cauth instruction
 
  // fuc5 crypt cauth instruction
  // Set auth_addr to 0x100, auth_size to 0x1300 and some unknown flags
+
  // Set auth_addr to 0x100, auth_size to 0x1300,
 +
// bit 16 (is_secret) and bit 17 (is_encrypted)
 
  cauth((0x02 << 0x10) | (0x01 << 0x10) | (0x1300 << 0x10) | (0x100 >> 0x08));
 
  cauth((0x02 << 0x10) | (0x01 << 0x10) | (0x1300 << 0x10) | (0x100 >> 0x08));
 
   
 
   
Line 1,796: Line 1,957:  
| 0x00
 
| 0x00
 
| 0x10
 
| 0x10
| Empty
+
| Debug key (empty)
 
|-
 
|-
 
| 0x10
 
| 0x10