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 |