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 ==