Fuses: Difference between revisions
m Hexkyz moved page Fuse registers to Fuses over redirect: More accurate page title |
documenting ipatches |
||
Line 88: | Line 88: | ||
==== FUSE_WRITE_ACCESS ==== | ==== FUSE_WRITE_ACCESS ==== | ||
If set to 0x01, this register disables software writes to the fuse driver registers. | If set to 0x01, this register disables software writes to the fuse driver registers. | ||
=== Cache registers === | === Cache registers === | ||
Line 575: | Line 574: | ||
=== bootrom_ipatch === | === bootrom_ipatch === | ||
Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse array using a specific format (see [https://gist.github.com/shuffle2/f8728159da100e9df2606d43925de0af shuffle2's ipatch decoder]). The bootrom reads these fuses in order to initialize the IPATCH hardware, which allows overriding data returned for code and data fetches done by BPMP. | Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse array using a specific format (see [https://gist.github.com/shuffle2/f8728159da100e9df2606d43925de0af shuffle2's ipatch decoder]). The bootrom reads these fuses in order to initialize the IPATCH hardware, which allows overriding data returned for code and data fetches done by BPMP. The revision stored in FUSE_CP_REV indicates the unique set of values stored in ipatch fuses. | ||
The revision stored in FUSE_CP_REV indicates the unique set of values stored in ipatch fuses. | |||
The following represents the patch data dumped from a Switch console: | The following represents the patch data dumped from a Switch console: | ||
Line 815: | Line 812: | ||
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices. | The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices. | ||
==== ipatch 0 ==== | |||
This patch configures clock enables and clock gate overrides for new hardware. | |||
<syntaxhighlight lang="c"> | |||
u32 CLK_ENB_H_SET = 0x60006328; | |||
u32 CLK_ENB_L_SET = 0x60006320; | |||
u32 CLK_ENB_U_SET = 0x60006330; | |||
u32 CLK_ENB_V_SET = 0x60006440; | |||
u32 CLK_ENB_W_SET = 0x60006448; | |||
u32 CLK_ENB_X_SET = 0x60006284; | |||
u32 CLK_ENB_Y_SET = 0x6000629C; | |||
u32 LVL2_CLK_GATE_OVRA = 0x600060F8; | |||
u32 LVL2_CLK_GATE_OVRB = 0x600060FC; | |||
u32 LVL2_CLK_GATE_OVRC = 0x600063A0; | |||
u32 LVL2_CLK_GATE_OVRD = 0x600063A4; | |||
u32 LVL2_CLK_GATE_OVRE = 0x60006554; | |||
u32 CLK_SOURCE_VI = 0x60006148; | |||
u32 CLK_SOURCE_HOST1X = 0x60006180; | |||
u32 CLK_SOURCE_NVENC = 0x600066A0; | |||
// Set all clock enables and overrides | |||
*(u32 *)CLK_ENB_V_SET = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_W_SET = 0xFFFFFFFF; | |||
*(u32 *)LVL2_CLK_GATE_OVRA = 0xFFFFFFFF; | |||
*(u32 *)LVL2_CLK_GATE_OVRB = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_X_SET = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_Y_SET = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_L_SET = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_H_SET = 0xFFFFFFFF; | |||
*(u32 *)CLK_ENB_U_SET = 0xFFFFFFFF; | |||
*(u32 *)LVL2_CLK_GATE_OVRC = 0xFFFFFFFF; | |||
*(u32 *)LVL2_CLK_GATE_OVRD = 0xFFFFFFFF; | |||
*(u32 *)LVL2_CLK_GATE_OVRE = 0xFFFFFFFF; | |||
// Set VI, HOST1X and NVENC clock sources to CLK_M | |||
*(u32 *)CLK_SOURCE_VI = 0xA0000000; | |||
*(u32 *)CLK_SOURCE_HOST1X = 0xA0000000; | |||
*(u32 *)CLK_SOURCE_NVENC = 0xE0000000; | |||
/* | |||
Untranslated instructions: | |||
MOVS R1, #0 | |||
MOVS R0, #0xE | |||
*/ | |||
return; | |||
</syntaxhighlight> | |||
==== ipatch 1 ==== | |||
This patch is a bugfix. | |||
LP0 resume code expects APBDEV_PMC_SCRATCH190_0 to be set to 0x01, but the bootrom didn't set it. | |||
<syntaxhighlight lang="c"> | |||
u32 APBDEV_PMC_SCRATCH190_0 = 0x7000EC18; | |||
u32 pmc_scratch190_val = *(u32 *)APBDEV_PMC_SCRATCH190_0; | |||
return (pmc_scratch190_val | 0x01); | |||
</syntaxhighlight> | |||
==== ipatch 2 ==== | |||
This patch adjusts USB configurations. | |||
<syntaxhighlight lang="c"> | |||
u32 USB1_UTMIP_SPARE_CFG0_0 = 0x7D000834; | |||
u32 USB1_UTMIP_BIAS_CFG2_0 = 0x7D000850; | |||
// Increase UTMIP_HSSQUELCH_LEVEL_NEW by 0x02 | |||
*(u32 *)USB1_UTMIP_BIAS_CFG2_0 += 0x02; | |||
// Clear FUSE_HS_IREF_CAP_CFG | |||
*(u32 *)USB1_UTMIP_SPARE_CFG0_0 = ((*(u32 *)USB1_UTMIP_SPARE_CFG0_0 & ~(0x118)) - 0x80); | |||
return; | |||
</syntaxhighlight> | |||
==== ipatch 3 ==== | |||
This patch pertains to XHCI IRQ clearing checks and forces a result code to be 0. | |||
==== ipatch 4 ==== | |||
This patch allows backing up and restoring strapping options for warmboot. | |||
<syntaxhighlight lang="c"> | |||
u32 APBDEV_PMC_SCRATCH0_0 = 0x7000E450; | |||
u32 APBDEV_PMC_RST_STATUS_0 = 0x7000E5B4; | |||
u32 APBDEV_PMC_SEC_DISABLE8_0 = 0x7000E9C0; | |||
u32 APBDEV_PMC_SECURE_SCRATCH111_0 = 0x7000EF14; | |||
u32 APB_MISC_PP_STRAPPING_OPT_A_0 = 0x70000008; | |||
u32 reset_status = *(u32 *)APBDEV_PMC_RST_STATUS_0; | |||
// Check for regular power on | |||
if (reset_status == 0) | |||
{ | |||
// Set all buttons in RCM_STRAPS and backup to PMC scratch | |||
*(u32 *)APBDEV_PMC_SECURE_SCRATCH111_0 = (*(u32 *)APB_MISC_PP_STRAPPING_OPT_A_0 | 0x1C00); | |||
} | |||
else | |||
{ | |||
// Restore strapping options from PMC scratch | |||
*(u32 *)APB_MISC_PP_STRAPPING_OPT_A_0 = *(u32 *)APBDEV_PMC_SECURE_SCRATCH111_0; | |||
} | |||
// Disable write access to APBDEV_PMC_SECURE_SCRATCH111_0 | |||
*(u32 *)APBDEV_PMC_SEC_DISABLE8_0 |= 0x4000; | |||
return *(u32 *)APBDEV_PMC_SCRATCH0_0; | |||
</syntaxhighlight> | |||
==== ipatch 5 ==== | |||
This patch adjusts USB configurations. | |||
<syntaxhighlight lang="c"> | |||
u32 USB1_UTMIP_HSRX_CFG0_0 = 0x7D000810; | |||
u32 USB1_UTMIP_BIAS_CFG2_0 = 0x7D000850; | |||
// Clear UTMIP_IDLE_WAIT, UTMIP_ELASTIC_LIMIT and UTMIP_PCOUNT_UPDN_DIV, | |||
// and set UTMIP_IDLE_WAIT to 0x11 and UTMIP_ELASTIC_LIMIT to 0x10 | |||
*(u32 *)USB1_UTMIP_HSRX_CFG0_0 = ((*(u32 *)USB1_UTMIP_HSRX_CFG0_0 & ~(0xF8000) + 0x88000 & ~(0x7C00) + 0x4000) & ~(0xF000000)); | |||
// Clear UTMIP_HSSQUELCH_LEVEL_NEW | |||
*(u32 *)USB1_UTMIP_BIAS_CFG2_0 &= ~(0x07); | |||
return; | |||
</syntaxhighlight> | |||
==== ipatch 6 ==== | |||
This patch is a factory backdoor. | |||
It allows controlling the debug authentication configuration using a fuse. | |||
<syntaxhighlight lang="c"> | |||
u32 FUSE_DEBUG_AUTH_OVERRIDE = 0x7000FA9C; | |||
u32 debug_auth_override_val = *(u32 *)FUSE_DEBUG_AUTH_OVERRIDE; | |||
debug_auth_override_val = ((debug_auth_override_val >> 0x08) << 0x01); | |||
// Override debug authentication value stored in IRAM | |||
*(u32 *)0x400028E4 &= ~(debug_auth_override_val); | |||
/* | |||
Untranslated instructions: | |||
CMP R0, #0 | |||
*/ | |||
return; | |||
</syntaxhighlight> | |||
==== ipatch 7 ==== | |||
This patch is a bugfix. | |||
It prevents overflowing IRAM (0x40010000) when copying the warmboot binary from DRAM. | |||
<syntaxhighlight lang="c"> | |||
u32 APBDEV_PMC_CNTRL_0 = 0x7000E400; | |||
u32 warmboot_header_addr = 0x400049F0; | |||
u32 warmboot_bin_size = *(u32 *)warmboot_bin_header_addr; | |||
// Invalid warmboot binary size | |||
if (warmboot_size >> 0x11) | |||
{ | |||
// Assert MAIN_RST | |||
// 0x40004BF0 comes from R4 and the bootrom doesn't bother to change it | |||
*(u32 *)APBDEV_PMC_CNTRL_0 = 0x40004BF0; | |||
// Deadlock | |||
while(1); | |||
} | |||
/* | |||
Untranslated instructions: | |||
LDR R0, =0x40010000 | |||
LDR R2, [warmboot_bin_header_addr] | |||
*/ | |||
return; | |||
</syntaxhighlight> | |||
==== ipatch 8 ==== | |||
This patch is a bugfix. | |||
It sets the correct warmboot binary entrypoint address for RSA signature verification, which would be done in DRAM instead of IRAM without this patch. | |||
<syntaxhighlight lang="c"> | |||
u32 warmboot_addr_ptr = 0x40010238; | |||
u32 warmboot_entry_addr_ptr = 0x40004C28; | |||
*(u32 *)warmboot_entry_addr_ptr = *(u32 *)warmboot_addr_ptr; | |||
/* | |||
Untranslated instructions: | |||
LDR R2, [warmboot_addr_ptr] | |||
*/ | |||
return; | |||
</syntaxhighlight> | |||
==== ipatches 9 and 10 ==== | |||
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A. | |||
==== ipatch 11 ==== | |||
This patch pertains to the [[Security_Engine|Security Engine]] context restore process and forces SE_OPERATION_UNK1 to be 0x01. | |||
== Anti-downgrade == | == Anti-downgrade == |