Changes

Jump to navigation Jump to search
31,741 bytes added ,  19:20, 11 June 2020
no edit summary
Line 1: Line 1: −
The Nintendo Switch makes use of Tegra's fuse driver for a number of operations. This driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming.
+
The Nintendo Switch uses the Tegra's fuse driver for accessing one time programmable data.
   −
Registers from 0x7000F800 to 0x7000F800 + 0xFF can be used to directly program the hardware fuse array, while registers from 0x7000F800 + 0x100 (FUSE_CHIP_REG_START_OFFSET) to 0x7000F800 + 0x3FC (FUSE_CHIP_REG_END_OFFSET) represent cached values read from certain fuses.
+
= Registers =
 +
The fuse driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming.
   −
== Registers ==
+
== Erista ==
Below is a list of fuse driver registers used by the Switch's bootloaders.
+
Registers from 0x7000F800 to 0x7000F800 + 0xFC represent the actual fuse [[#Driver|driver]] which can be used to directly program the hardware fuse bitmap.
   −
=== Driver registers ===
+
Registers from 0x7000F800 + 0x100 (FUSE_CHIP_REG_START_OFFSET) to 0x7000F800 + 0x3FC (FUSE_CHIP_REG_END_OFFSET) represent the fuse [[#Cache|cache]] which holds the sensed values of certain fuses.
 +
 
 +
=== Driver ===
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  Name
 
!  Name
Line 23: Line 26:  
| 0x7000F80C
 
| 0x7000F80C
 
|-
 
|-
| FUSE_FUSETIME_RD1
+
| [[#FUSE_FUSETIME_RD1|FUSE_FUSETIME_RD1]]
 
| 0x7000F810
 
| 0x7000F810
 
|-
 
|-
| FUSE_FUSETIME_RD2
+
| [[#FUSE_FUSETIME_RD2|FUSE_FUSETIME_RD2]]
 
| 0x7000F814
 
| 0x7000F814
 
|-
 
|-
| FUSE_FUSETIME_PGM1
+
| [[#FUSE_FUSETIME_PGM1|FUSE_FUSETIME_PGM1]]
 
| 0x7000F818
 
| 0x7000F818
 
|-
 
|-
Line 38: Line 41:  
| 0x7000F820
 
| 0x7000F820
 
|-
 
|-
| FUSE_FUSEBYPASS
+
| [[#FUSE_FUSEBYPASS|FUSE_FUSEBYPASS]]
 
| 0x7000F824
 
| 0x7000F824
 
|-
 
|-
| FUSE_PRIVATEKEYDISABLE
+
| [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]]
 
| 0x7000F828
 
| 0x7000F828
 
|-
 
|-
Line 50: Line 53:  
| 0x7000F830
 
| 0x7000F830
 
|-
 
|-
| FUSE_PWR_GOOD_SW
+
| [[#FUSE_PRIV2RESHIFT|FUSE_PRIV2RESHIFT]]
| 0x7000F834
  −
|-
  −
| FUSE_PRIV2RESHIFT
   
| 0x7000F83C
 
| 0x7000F83C
 
|-
 
|-
| FUSE_FUSETIME_RD3
+
| [[#FUSE_FUSETIME_RD3|FUSE_FUSETIME_RD3]]
 
| 0x7000F84C
 
| 0x7000F84C
 
|-
 
|-
| FUSE_PRIVATE_KEY0_NONZERO
+
| [[#FUSE_PRIVATE_KEY0_NONZERO|FUSE_PRIVATE_KEY0_NONZERO]]
 
| 0x7000F880
 
| 0x7000F880
 
|-
 
|-
| FUSE_PRIVATE_KEY1_NONZERO
+
| [[#FUSE_PRIVATE_KEY1_NONZERO|FUSE_PRIVATE_KEY1_NONZERO]]
 
| 0x7000F884
 
| 0x7000F884
 
|-
 
|-
| FUSE_PRIVATE_KEY2_NONZERO
+
| [[#FUSE_PRIVATE_KEY2_NONZERO|FUSE_PRIVATE_KEY2_NONZERO]]
 
| 0x7000F888
 
| 0x7000F888
 
|-
 
|-
| FUSE_PRIVATE_KEY3_NONZERO
+
| [[#FUSE_PRIVATE_KEY3_NONZERO|FUSE_PRIVATE_KEY3_NONZERO]]
 
| 0x7000F88C
 
| 0x7000F88C
 
|-
 
|-
| FUSE_PRIVATE_KEY4_NONZERO
+
| [[#FUSE_PRIVATE_KEY4_NONZERO|FUSE_PRIVATE_KEY4_NONZERO]]
 
| 0x7000F890
 
| 0x7000F890
 
|}
 
|}
Line 104: Line 104:  
  0x0D: STATE_WRITE_ADDR_HOLD
 
  0x0D: STATE_WRITE_ADDR_HOLD
 
  0x0E: STATE_FUSE_SRC_HOLD
 
  0x0E: STATE_FUSE_SRC_HOLD
  0x0F: STATE_READ_BEFORE_WRITE_SETUP
+
  0x0F: STATE_LOAD_RIR
 +
0x10: STATE_READ_BEFORE_WRITE_SETUP
 +
0x11: STATE_READ_DEASSERT_PD
 
|-
 
|-
 
| 21
 
| 21
Line 131: Line 133:  
|}
 
|}
   −
Before fuse reading/writing the power down mode must be disabled.
+
FUSE_FUSECTRL_CMD takes the fuse controller's operation mode. READ and WRITE interact directly with the hardware fuse bitmap while SENSE_CTRL flushes programmed values into the [[Fuses#Cache_registers|cache registers]].
SENSE_CTRL mode flushes programmed values into the [[Fuses#Cache_registers|cache registers]].
+
 
 +
FUSE_FUSECTRL_STATE returns the current state of the fuse controller.
 +
 
 +
FUSE_FUSECTRL_MARGIN_READ changes the fuse read trip point setting to margin read mode.
 +
 
 +
FUSE_FUSECTRL_RWL selects the fuse redundancy information row.
   −
==== FUSE_FUSEADDR ====
+
FUSE_FUSECTRL_TRCS triggers record shifting.
This register takes the address of the fuse to be read/written/sensed.
     −
==== FUSE_FUSERDATA ====
+
FUSE_FUSECTRL_PD_CTRL controls the fuse macro's power down mode.
This register receives the value read from the fuse.
     −
==== FUSE_FUSEWDATA ====
+
FUSE_FUSECTRL_FUSE_SENSE_DONE is set if fuse sensing is completed.
This register takes the value to be written to the fuse.
     −
==== FUSE_FUSETIME_PGM2 ====
+
FUSE_FUSECTRL_RECORD_SHIFT_DONE is set if record shifting is completed.
This register takes the fuse programming pulse (0xC0 == 19200 kHz).
     −
==== FUSE_PRIV2INTFC_START ====
+
==== FUSE_FUSEADDR ====
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  Bits
 
!  Bits
 
!  Description
 
!  Description
 
|-
 
|-
| 0
+
| 0-7
| FUSE_PRIV2INTFC_START_DATA
+
| FUSE_FUSEADDR_VLDFLD
 +
|}
 +
 
 +
Takes the address of the fuse to be read/written/sensed.
 +
 
 +
==== FUSE_FUSERDATA ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| 1
+
| 0-31
| FUSE_PRIV2INTFC_START_SKIP_RECORDS
+
| FUSE_FUSERDATA_DATA
 
|}
 
|}
   −
==== FUSE_DISABLEREGPROGRAM ====
+
Returns the value read from the fuse.
If set to 0x01, this register disables fuse programming.
  −
 
  −
==== FUSE_WRITE_ACCESS_SW ====
  −
If set to 0x01, this register disables software writes to the fuse driver registers.
     −
=== Cache registers ===
+
==== FUSE_FUSEWDATA ====
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Name
+
Bits
Address
+
Description
 
|-
 
|-
| FUSE_PRODUCTION_MODE
+
| 0-31
| 0x7000F900
+
| FUSE_FUSEWDATA_DATA
 +
|}
 +
 
 +
Takes the value to be written to the fuse.
 +
 
 +
==== FUSE_FUSETIME_RD1 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_JTAG_SECUREID_VALID
+
| 0-7
| 0x7000F904
+
| FUSE_FUSETIME_RD1_TSUR_MAX
 
|-
 
|-
| FUSE_ODM_LOCK
+
| 8-15
| 0x7000F908
+
| FUSE_FUSETIME_RD1_TSUR_FUSEOUT
 
|-
 
|-
| FUSE_OPT_OPENGL_EN
+
| 16-23
| 0x7000F90C
+
| FUSE_FUSETIME_RD1_THR_MAX
 +
|}
 +
 
 +
FUSE_FUSETIME_RD1_TSUR_MAX takes the maximum time for [[#FUSE_FUSECTRL|STATE_READ_SETUP]].
 +
 
 +
FUSE_FUSETIME_RD1_TSUR_FUSEOUT takes the time to spend on [[#FUSE_FUSECTRL|STATE_SAMPLE_FUSES]].
 +
 
 +
FUSE_FUSETIME_RD1_THR_MAX takes the maximum time for [[#FUSE_FUSECTRL|STATE_READ_HOLD]].
 +
 
 +
==== FUSE_FUSETIME_RD2 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_SKU_INFO|FUSE_SKU_INFO]]
+
| 0-15
| 0x7000F910
+
| FUSE_FUSETIME_RD2_TWIDTH_RD
 +
|}
 +
 
 +
Takes the read strobe pulse width used during [[#FUSE_FUSECTRL|STATE_READ_STROBE]].
 +
 
 +
==== FUSE_FUSETIME_PGM1 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_CPU_SPEEDO_0_CALIB
+
| 0-7
| 0x7000F914
+
| FUSE_FUSETIME_PGM1_TSUP_MAX
 
|-
 
|-
| FUSE_CPU_IDDQ_CALIB
+
| 8-15
| 0x7000F918
+
| FUSE_FUSETIME_PGM1_TSUP_ADDR
 
|-
 
|-
| FUSE_DAC_CRT_CALIB
+
| 16-23
| 0x7000F91C
+
| FUSE_FUSETIME_PGM1_THP_ADDR
 
|-
 
|-
| FUSE_DAC_HDTV_CALIB
+
| 24-31
| 0x7000F920
+
| FUSE_FUSETIME_PGM1_THP_PS
 +
|}
 +
 
 +
FUSE_FUSETIME_PGM1_TSUP_MAX takes the maximum time for [[#FUSE_FUSECTRL|STATE_WRITE_SETUP]].
 +
 
 +
FUSE_FUSETIME_PGM1_TSUP_ADDR takes the time to spend on [[#FUSE_FUSECTRL|STATE_WRITE_ADDR_SETUP]].
 +
 
 +
FUSE_FUSETIME_PGM1_THP_ADDR takes the time to spend on [[#FUSE_FUSECTRL|STATE_WRITE_ADDR_HOLD]].
 +
 
 +
FUSE_FUSETIME_PGM1_THP_PS takes the time to spend on [[#FUSE_FUSECTRL|STATE_FUSE_SRC_HOLD]].
 +
 
 +
==== FUSE_FUSETIME_PGM2 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_DAC_SDTV_CALIB
+
| 0-15
| 0x7000F924
+
| FUSE_FUSETIME_PGM2_TWIDTH_PGM
 
|-
 
|-
| [[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]]
+
| 16-23
| 0x7000F928
+
| FUSE_FUSETIME_PGM2_TSUP_PS
 
|-
 
|-
| FUSE_CPU_SPEEDO_1_CALIB
+
| 24-31
| 0x7000F92C
+
| FUSE_FUSETIME_PGM2_THP_CSPS
 +
|}
 +
 
 +
FUSE_FUSETIME_PGM2_TWIDTH_PGM takes the program strobe pulse width used during [[#FUSE_FUSECTRL|STATE_WRITE_PROGRAM]].
 +
 
 +
FUSE_FUSETIME_PGM2_TSUP_PS takes the time to spend on [[#FUSE_FUSECTRL|STATE_FUSE_SRC_SETUP]].
 +
 
 +
FUSE_FUSETIME_PGM2_THP_CSPS takes the time to spend on [[#FUSE_FUSECTRL|STATE_READ_BEFORE_WRITE_SETUP]].
 +
 
 +
==== FUSE_PRIV2INTFC_START ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_CPU_SPEEDO_2_CALIB
+
| 0
| 0x7000F930
+
| FUSE_PRIV2INTFC_START_DATA
 
|-
 
|-
| FUSE_SOC_SPEEDO_0_CALIB
+
| 1
| 0x7000F934
+
| FUSE_PRIV2INTFC_SKIP_RECORDS
 +
|}
 +
 
 +
Controls the interface between the internal fuse chip (INTFC) and the fuse cache registers (PRIV).
 +
 
 +
==== FUSE_FUSEBYPASS ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_SOC_SPEEDO_1_CALIB|FUSE_SOC_SPEEDO_1_CALIB]]
+
| 0
| 0x7000F938
+
| FUSE_FUSEBYPASS_VAL
 +
|}
 +
 
 +
If set, this register enables fuse bypass mode. This is only available in hardware where the [[#Bitmap|production_mode]] fuse remains unburnt.
 +
 
 +
==== FUSE_PRIVATEKEYDISABLE ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_SOC_SPEEDO_2_CALIB
+
| 0
| 0x7000F93C
+
| FUSE_PRIVATEKEYDISABLE_VAL
 
|-
 
|-
| FUSE_SOC_IDDQ_CALIB
+
| 4
| 0x7000F940
+
| FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT_VAL
|-
+
|}
| FUSE_RESERVED_PRODUCTION_WP
+
 
| 0x7000F944
+
If set, this register hides the [[#Bitmap|private_key]] fuses until the next reset.
 +
 
 +
==== FUSE_DISABLEREGPROGRAM ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_FA|FUSE_FA]]
+
| 0
| 0x7000F948
+
| FUSE_DISABLEREGPROGRAM_VAL
 +
|}
 +
 
 +
If set, this register disables fuse programming until the next reset.
 +
 
 +
==== FUSE_WRITE_ACCESS_SW ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_RESERVED_PRODUCTION
+
| 0
| 0x7000F94C
+
| FUSE_WRITE_ACCESS_SW_CTRL
 
|-
 
|-
| FUSE_HDMI_LANE0_CALIB
+
| 16
| 0x7000F950
+
| FUSE_WRITE_ACCESS_SW_STATUS
 +
|}
 +
 
 +
Controls and returns the status of software writes to the fuse cache registers.
 +
 
 +
==== FUSE_PRIV2RESHIFT ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_HDMI_LANE1_CALIB
+
| 0
| 0x7000F954
+
| FUSE_PRIV2RESHIFT_TRIGENABLE_VAL
 
|-
 
|-
| FUSE_HDMI_LANE2_CALIB
+
| 1
| 0x7000F958
+
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU0_VAL
 
|-
 
|-
| FUSE_HDMI_LANE3_CALIB
+
| 2
| 0x7000F95C
+
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU1_VAL
 
|-
 
|-
| FUSE_ENCRYPTION_RATE
+
| 3
| 0x7000F960
+
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU2_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY0]]
+
| 4
| 0x7000F964
+
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU3_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY1]]
+
| 5
| 0x7000F968
+
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK0_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY2]]
+
| 6
| 0x7000F96C
+
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK1_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY3]]
+
| 7
| 0x7000F970
+
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK2_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY4]]
+
| 8
| 0x7000F974
+
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK3_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY5]]
+
| 9
| 0x7000F978
+
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU0_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY6]]
+
| 10
| 0x7000F97C
+
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU1_VAL
 
|-
 
|-
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY7]]
+
| 11
| 0x7000F980
+
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU2_VAL
 
|-
 
|-
| FUSE_TSENSOR1_CALIB
+
| 12
| 0x7000F984
+
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU3_VAL
 
|-
 
|-
| FUSE_TSENSOR2_CALIB
+
| 13
| 0x7000F988
+
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK0_VAL
 
|-
 
|-
| FUSE_VSENSOR_CALIB
+
| 14
| 0x7000F98C
+
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK1_VAL
 
|-
 
|-
| [[#FUSE_OPT_CP_REV|FUSE_OPT_CP_REV]]
+
| 15
| 0x7000F990
+
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK2_VAL
 
|-
 
|-
| FUSE_OPT_PFG
+
| 16
| 0x7000F994
+
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK3_VAL
 +
|}
 +
 
 +
Controls and returns the status of the record shift (RESHIFT) hardware block used for RAM re-repair.
 +
 
 +
==== FUSE_FUSETIME_RD3 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_TSENSOR0_CALIB
+
| 0-15
| 0x7000F998
+
| FUSE_FUSETIME_RD3_TSUR_PDCS
 +
|}
 +
 
 +
Takes the time to spend on [[#FUSE_FUSECTRL|STATE_READ_DEASSERT_PD]].
 +
 
 +
==== FUSE_PRIVATE_KEY0_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| FUSE_FIRST_BOOTROM_PATCH_SIZE
+
| 0
| 0x7000F99C
+
| FUSE_PRIVATE_KEY0_NONZERO_DATA
|-
+
|}
| FUSE_SECURITY_MODE
+
 
| 0x7000F9A0
+
Returns whether [[#Bitmap|private_key0]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY1_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY0]]
+
| 0
| 0x7000F9A4
+
| FUSE_PRIVATE_KEY1_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key1]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY2_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY1]]
+
| 0
| 0x7000F9A8
+
| FUSE_PRIVATE_KEY2_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key2]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY3_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY2]]
+
| 0
| 0x7000F9AC
+
| FUSE_PRIVATE_KEY3_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key3]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY4_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY3]]
+
| 0
| 0x7000F9B0
+
| FUSE_PRIVATE_KEY4_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key4]] is empty or not.
 +
 
 +
=== Cache ===
 +
{| class="wikitable" border="1"
 +
!  Name
 +
!  Address
 
|-
 
|-
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY4]]
+
| FUSE_PRODUCTION_MODE
| 0x7000F9B4
+
| 0x7000F900
 
|-
 
|-
| FUSE_ARM_JTAG_DIS
+
| FUSE_JTAG_SECUREID_VALID
| 0x7000F9B8
+
| 0x7000F904
 
|-
 
|-
| FUSE_BOOT_DEVICE_INFO
+
| FUSE_ODM_LOCK
| 0x7000F9BC
+
| 0x7000F908
 
|-
 
|-
| [[#FUSE_RESERVED_SW|FUSE_RESERVED_SW]]
+
| FUSE_OPT_OPENGL_EN
| 0x7000F9C0
+
| 0x7000F90C
 
|-
 
|-
| FUSE_OPT_VP9_DISABLE
+
| [[#FUSE_SKU_INFO|FUSE_SKU_INFO]]
| 0x7000F9C4
+
| 0x7000F910
 
|-
 
|-
| [[#FUSE_RESERVED_ODM0|FUSE_RESERVED_ODM0]]
+
| FUSE_CPU_SPEEDO_0_CALIB
| 0x7000F9C8
+
| 0x7000F914
 
|-
 
|-
| [[#FUSE_RESERVED_ODM1|FUSE_RESERVED_ODM1]]
+
| FUSE_CPU_IDDQ_CALIB
| 0x7000F9CC
+
| 0x7000F918
 
|-
 
|-
| [[#FUSE_RESERVED_ODM2|FUSE_RESERVED_ODM2]]
+
| [[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]]
| 0x7000F9D0
+
| 0x7000F928
 
|-
 
|-
| [[#FUSE_RESERVED_ODM3|FUSE_RESERVED_ODM3]]
+
| FUSE_CPU_SPEEDO_1_CALIB
| 0x7000F9D4
+
| 0x7000F92C
 
|-
 
|-
| [[#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]
+
| FUSE_CPU_SPEEDO_2_CALIB
| 0x7000F9D8
+
| 0x7000F930
 
|-
 
|-
| FUSE_RESERVED_ODM5
+
| FUSE_SOC_SPEEDO_0_CALIB
| 0x7000F9DC
+
| 0x7000F934
 
|-
 
|-
| [[#FUSE_RESERVED_ODM6|FUSE_RESERVED_ODM6]]
+
| [[#FUSE_SOC_SPEEDO_1_CALIB|FUSE_SOC_SPEEDO_1_CALIB]]
| 0x7000F9E0
+
| 0x7000F938
 
|-
 
|-
| [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]]
+
| FUSE_SOC_SPEEDO_2_CALIB
| 0x7000F9E4
+
| 0x7000F93C
 
|-
 
|-
| FUSE_OBS_DIS
+
| FUSE_SOC_IDDQ_CALIB
| 0x7000F9E8
+
| 0x7000F940
 
|-
 
|-
| FUSE_NOR_INFO
+
| [[#FUSE_FA|FUSE_FA]]
| 0x7000F9EC
+
| 0x7000F948
 
|-
 
|-
| FUSE_USB_CALIB
+
| FUSE_RESERVED_PRODUCTION
| 0x7000F9F0
+
| 0x7000F94C
 
|-
 
|-
| FUSE_SKU_DIRECT_CONFIG
+
| FUSE_HDMI_LANE0_CALIB
| 0x7000F9F4
+
| 0x7000F950
 
|-
 
|-
| FUSE_KFUSE_PRIVKEY_CTRL
+
| FUSE_HDMI_LANE1_CALIB
| 0x7000F9F8
+
| 0x7000F954
 
|-
 
|-
| FUSE_PACKAGE_INFO
+
| FUSE_HDMI_LANE2_CALIB
| 0x7000F9FC
+
| 0x7000F958
 
|-
 
|-
| FUSE_OPT_VENDOR_CODE
+
| FUSE_HDMI_LANE3_CALIB
| 0x7000FA00
+
| 0x7000F95C
 
|-
 
|-
| FUSE_OPT_FAB_CODE
+
| FUSE_ENCRYPTION_RATE
| 0x7000FA04
+
| 0x7000F960
 
|-
 
|-
| FUSE_OPT_LOT_CODE_0
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY0]]
| 0x7000FA08
+
| 0x7000F964
 
|-
 
|-
| FUSE_OPT_LOT_CODE_1
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY1]]
| 0x7000FA0C
+
| 0x7000F968
 
|-
 
|-
| FUSE_OPT_WAFER_ID
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY2]]
| 0x7000FA10
+
| 0x7000F96C
 
|-
 
|-
| FUSE_OPT_X_COORDINATE
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY3]]
| 0x7000FA14
+
| 0x7000F970
 
|-
 
|-
| FUSE_OPT_Y_COORDINATE
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY4]]
| 0x7000FA18
+
| 0x7000F974
 
|-
 
|-
| FUSE_OPT_SEC_DEBUG_EN
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY5]]
| 0x7000FA1C
+
| 0x7000F978
 
|-
 
|-
| FUSE_OPT_OPS_RESERVED
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY6]]
| 0x7000FA20
+
| 0x7000F97C
 
|-
 
|-
| FUSE_SATA_CALIB
+
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY7]]
| 0x7000FA24
+
| 0x7000F980
 
|-
 
|-
| FUSE_GPU_IDDQ_CALIB
+
| FUSE_TSENSOR1_CALIB
| 0x7000FA28
+
| 0x7000F984
 
|-
 
|-
| FUSE_TSENSOR3_CALIB
+
| FUSE_TSENSOR2_CALIB
| 0x7000FA2C
+
| 0x7000F988
 
|-
 
|-
| FUSE_SKU_BOND_OUT_L
+
| [[#FUSE_OPT_CP_REV|FUSE_OPT_CP_REV]]
| 0x7000FA30
+
| 0x7000F990
 
|-
 
|-
| FUSE_SKU_BOND_OUT_H
+
| FUSE_OPT_PFG
| 0x7000FA34
+
| 0x7000F994
 
|-
 
|-
| FUSE_SKU_BOND_OUT_U
+
| FUSE_TSENSOR0_CALIB
| 0x7000FA38
+
| 0x7000F998
 
|-
 
|-
| FUSE_SKU_BOND_OUT_V
+
| FUSE_FIRST_BOOTROM_PATCH_SIZE
| 0x7000FA3C
+
| 0x7000F99C
 
|-
 
|-
| FUSE_SKU_BOND_OUT_W
+
| FUSE_SECURITY_MODE
| 0x7000FA40
+
| 0x7000F9A0
 
|-
 
|-
| FUSE_OPT_SAMPLE_TYPE
+
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY0]]
| 0x7000FA44
+
| 0x7000F9A4
 
|-
 
|-
| FUSE_OPT_SUBREVISION
+
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY1]]
| 0x7000FA48
+
| 0x7000F9A8
 
|-
 
|-
| FUSE_OPT_SW_RESERVED_0
+
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY2]]
| 0x7000FA4C
+
| 0x7000F9AC
 
|-
 
|-
| FUSE_OPT_SW_RESERVED_1
+
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY3]]
| 0x7000FA50
+
| 0x7000F9B0
 
|-
 
|-
| FUSE_TSENSOR4_CALIB
+
| [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY4]]
| 0x7000FA54
+
| 0x7000F9B4
 
|-
 
|-
| FUSE_TSENSOR5_CALIB
+
| FUSE_ARM_JTAG_DIS
| 0x7000FA58
+
| 0x7000F9B8
 
|-
 
|-
| FUSE_TSENSOR6_CALIB
+
| FUSE_BOOT_DEVICE_INFO
| 0x7000FA5C
+
| 0x7000F9BC
 
|-
 
|-
| FUSE_TSENSOR7_CALIB
+
| [[#FUSE_RESERVED_SW|FUSE_RESERVED_SW]]
| 0x7000FA60
+
| 0x7000F9C0
 
|-
 
|-
| FUSE_OPT_PRIV_SEC_EN
+
| FUSE_OPT_VP9_DISABLE
| 0x7000FA64
+
| 0x7000F9C4
 
|-
 
|-
| [[#FUSE_PKC_DISABLE|FUSE_PKC_DISABLE]]
+
| [[#FUSE_RESERVED_ODM0|FUSE_RESERVED_ODM0]]
| 0x7000FA68
+
| 0x7000F9C8
 
|-
 
|-
| FUSE_FUSE2TSEC_DEBUG_DISABLE
+
| [[#FUSE_RESERVED_ODM1|FUSE_RESERVED_ODM1]]
| 0x7000FA7C
+
| 0x7000F9CC
 
|-
 
|-
| FUSE_TSENSOR_COMMON
+
| [[#FUSE_RESERVED_ODM2|FUSE_RESERVED_ODM2]]
| 0x7000FA80
+
| 0x7000F9D0
 
|-
 
|-
| FUSE_OPT_CP_BIN
+
| [[#FUSE_RESERVED_ODM3|FUSE_RESERVED_ODM3]]
| 0x7000FA84
+
| 0x7000F9D4
 
|-
 
|-
| FUSE_OPT_GPU_DISABLE
+
| [[#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]
| 0x7000FA88
+
| 0x7000F9D8
 
|-
 
|-
| FUSE_OPT_FT_BIN
+
| FUSE_RESERVED_ODM5
| 0x7000FA8C
+
| 0x7000F9DC
 
|-
 
|-
| FUSE_OPT_DONE_MAP
+
| [[#FUSE_RESERVED_ODM6|FUSE_RESERVED_ODM6]]
| 0x7000FA90
+
| 0x7000F9E0
 
|-
 
|-
| FUSE_APB2JTAG_DISABLE
+
| [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]]
| 0x7000FA98
+
| 0x7000F9E4
 
|-
 
|-
| FUSE_ODM_INFO
+
| FUSE_OBS_DIS
| 0x7000FA9C
+
| 0x7000F9E8
 
|-
 
|-
| FUSE_ARM_CRYPT_DE_FEATURE
+
| FUSE_USB_CALIB
| 0x7000FAA8
+
| 0x7000F9F0
 
|-
 
|-
| FUSE_WOA_SKU_FLAG
+
| FUSE_SKU_DIRECT_CONFIG
| 0x7000FAC0
+
| 0x7000F9F4
 
|-
 
|-
| FUSE_ECO_RESERVE_1
+
| FUSE_KFUSE_PRIVKEY_CTRL
| 0x7000FAC4
+
| 0x7000F9F8
 
|-
 
|-
| FUSE_GCPLEX_CONFIG_FUSE
+
| FUSE_PACKAGE_INFO
| 0x7000FAC8
+
| 0x7000F9FC
 
|-
 
|-
| FUSE_PRODUCTION_MONTH
+
| FUSE_OPT_VENDOR_CODE
| 0x7000FACC
+
| 0x7000FA00
 
|-
 
|-
| FUSE_RAM_REPAIR_INDICATOR
+
| FUSE_OPT_FAB_CODE
| 0x7000FAD0
+
| 0x7000FA04
 
|-
 
|-
| FUSE_TSENSOR9_CALIB
+
| FUSE_OPT_LOT_CODE_0
| 0x7000FAD4
+
| 0x7000FA08
 
|-
 
|-
| FUSE_VMIN_CALIBRATION
+
| FUSE_OPT_LOT_CODE_1
| 0x7000FADC
+
| 0x7000FA0C
 
|-
 
|-
| FUSE_AGING_SENSOR_CALIBRATION
+
| FUSE_OPT_WAFER_ID
| 0x7000FAE0
+
| 0x7000FA10
 
|-
 
|-
| FUSE_DEBUG_AUTHENTICATION
+
| FUSE_OPT_X_COORDINATE
| 0x7000FAE4
+
| 0x7000FA14
 
|-
 
|-
| FUSE_SECURE_PROVISION_INDEX
+
| FUSE_OPT_Y_COORDINATE
| 0x7000FAE8
+
| 0x7000FA18
 
|-
 
|-
| FUSE_SECURE_PROVISION_INFO
+
| [[#FUSE_OPT_SEC_DEBUG_EN|FUSE_OPT_SEC_DEBUG_EN]]
| 0x7000FAEC
+
| 0x7000FA1C
 
|-
 
|-
| FUSE_OPT_GPU_DISABLE_CP1
+
| FUSE_OPT_OPS_RESERVED
| 0x7000FAF0
+
| 0x7000FA20
 
|-
 
|-
| FUSE_SPARE_ENDIS
+
| FUSE_SATA_CALIB
| 0x7000FAF4
+
| 0x7000FA24
 
|-
 
|-
| FUSE_ECO_RESERVE_0
+
| FUSE_GPU_IDDQ_CALIB
| 0x7000FAF8
+
| 0x7000FA28
 
|-
 
|-
| FUSE_SPARE_REALIGNMENT_REG_OLD
+
| FUSE_TSENSOR3_CALIB
| 0x7000FAFC
+
| 0x7000FA2C
 
|-
 
|-
| FUSE_RESERVED_CALIB0
+
| FUSE_CLOCK_BOUNDOUT0
| 0x7000FB04
+
| 0x7000FA30
 
|-
 
|-
| FUSE_RESERVED_CALIB1
+
| FUSE_CLOCK_BOUNDOUT1
| 0x7000FB08
+
| 0x7000FA34
 
|-
 
|-
| FUSE_OPT_GPU_TPC0_DISABLE
+
| FUSE_OPT_SAMPLE_TYPE
| 0x7000FB0C
+
| 0x7000FA44
 
|-
 
|-
| FUSE_OPT_GPU_TPC0_DISABLE_CP1
+
| FUSE_OPT_SUBREVISION
| 0x7000FB10
+
| 0x7000FA48
 
|-
 
|-
| FUSE_OPT_CPU_DISABLE
+
| FUSE_OPT_SW_RESERVED_0
| 0x7000FB14
+
| 0x7000FA4C
 
|-
 
|-
| FUSE_OPT_CPU_DISABLE_CP1
+
| FUSE_OPT_SW_RESERVED_1
| 0x7000FB18
+
| 0x7000FA50
 
|-
 
|-
| FUSE_TSENSOR10_CALIB
+
| FUSE_TSENSOR4_CALIB
| 0x7000FB1C
+
| 0x7000FA54
 
|-
 
|-
| FUSE_TSENSOR10_CALIB_AUX
+
| FUSE_TSENSOR5_CALIB
| 0x7000FB20
+
| 0x7000FA58
 
|-
 
|-
| FUSE_OPT_RAM_SVOP_DP
+
| FUSE_TSENSOR6_CALIB
| 0x7000FB24
+
| 0x7000FA5C
 
|-
 
|-
| FUSE_OPT_RAM_SVOP_PDP
+
| FUSE_TSENSOR7_CALIB
| 0x7000FB28
+
| 0x7000FA60
 
|-
 
|-
| FUSE_OPT_RAM_SVOP_REG
+
| [[#FUSE_OPT_PRIV_SEC_EN|FUSE_OPT_PRIV_SEC_EN]]
| 0x7000FB2C
+
| 0x7000FA64
 
|-
 
|-
| FUSE_OPT_RAM_SVOP_SP
+
| [[#FUSE_PKC_DISABLE|FUSE_PKC_DISABLE]]
| 0x7000FB30
+
| 0x7000FA68
 
|-
 
|-
| FUSE_OPT_RAM_SVOP_SMPDP
+
| FUSE_FUSE2TSEC_DEBUG_DISABLE
| 0x7000FB34
+
| 0x7000FA7C
 
|-
 
|-
| FUSE_OPT_GPU_TPC0_DISABLE_CP2
+
| FUSE_TSENSOR_COMMON
| 0x7000FB38
+
| 0x7000FA80
 
|-
 
|-
| FUSE_OPT_GPU_TPC1_DISABLE
+
| FUSE_OPT_CP_BIN
| 0x7000FB3C
+
| 0x7000FA84
 
|-
 
|-
| FUSE_OPT_GPU_TPC1_DISABLE_CP1
+
| FUSE_OPT_GPU_DISABLE
| 0x7000FB40
+
| 0x7000FA88
 
|-
 
|-
| FUSE_OPT_GPU_TPC1_DISABLE_CP2
+
| FUSE_OPT_FT_BIN
| 0x7000FB44
+
| 0x7000FA8C
 
|-
 
|-
| FUSE_OPT_CPU_DISABLE_CP2
+
| FUSE_OPT_DONE_MAP
| 0x7000FB48
+
| 0x7000FA90
 
|-
 
|-
| FUSE_OPT_GPU_DISABLE_CP2
+
| FUSE_APB2JTAG_DISABLE
| 0x7000FB4C
+
| 0x7000FA98
 
|-
 
|-
| FUSE_USB_CALIB_EXT
+
| FUSE_ODM_INFO
| 0x7000FB50
+
| 0x7000FA9C
 
|-
 
|-
| FUSE_RESERVED_FIELD
+
| FUSE_ARM_CRYPT_DE_FEATURE
| 0x7000FB54
+
| 0x7000FAA8
 
|-
 
|-
| FUSE_OPT_ECC_EN
+
| FUSE_WOA_SKU_FLAG
| 0x7000FB58
+
| 0x7000FAC0
 
|-
 
|-
| FUSE_SPARE_REALIGNMENT_REG
+
| FUSE_ECO_RESERVE_1
| 0x7000FB7C
+
| 0x7000FAC4
 
|-
 
|-
| FUSE_SPARE_BIT_0
+
| FUSE_GCPLEX_CONFIG_FUSE
| 0x7000FB80
+
| 0x7000FAC8
 
|-
 
|-
| FUSE_SPARE_BIT_1
+
| FUSE_PRODUCTION_MONTH
| 0x7000FB84
+
| 0x7000FACC
 
|-
 
|-
| [[#FUSE_SPARE_BIT_2|FUSE_SPARE_BIT_2]]
+
| FUSE_RAM_REPAIR_INDICATOR
| 0x7000FB88
+
| 0x7000FAD0
 
|-
 
|-
| [[#FUSE_SPARE_BIT_3|FUSE_SPARE_BIT_3]]
+
| FUSE_TSENSOR9_CALIB
| 0x7000FB8C
+
| 0x7000FAD4
 
|-
 
|-
| [[#FUSE_SPARE_BIT_4|FUSE_SPARE_BIT_4]]
+
| FUSE_VMIN_CALIBRATION
| 0x7000FB90
+
| 0x7000FADC
 
|-
 
|-
| [[#FUSE_SPARE_BIT_5|FUSE_SPARE_BIT_5]]
+
| FUSE_AGING_SENSOR_CALIBRATION
| 0x7000FB94
+
| 0x7000FAE0
 
|-
 
|-
| FUSE_SPARE_BIT_6
+
| FUSE_DEBUG_AUTHENTICATION
| 0x7000FB98
+
| 0x7000FAE4
 
|-
 
|-
| FUSE_SPARE_BIT_7
+
| FUSE_SECURE_PROVISION_INDEX
| 0x7000FB9C
+
| 0x7000FAE8
 
|-
 
|-
| FUSE_SPARE_BIT_8
+
| FUSE_SECURE_PROVISION_INFO
| 0x7000FBA0
+
| 0x7000FAEC
 
|-
 
|-
| FUSE_SPARE_BIT_9
+
| FUSE_OPT_GPU_DISABLE_CP1
| 0x7000FBA4
+
| 0x7000FAF0
 
|-
 
|-
| FUSE_SPARE_BIT_10
+
| FUSE_SPARE_ENDIS
| 0x7000FBA8
+
| 0x7000FAF4
 
|-
 
|-
| FUSE_SPARE_BIT_11
+
| [[#FUSE_ECO_RESERVE_0|FUSE_ECO_RESERVE_0]]
| 0x7000FBAC
+
| 0x7000FAF8
 
|-
 
|-
| FUSE_SPARE_BIT_12
+
| FUSE_RESERVED_CALIB0
| 0x7000FBB0
+
| 0x7000FB04
 
|-
 
|-
| FUSE_SPARE_BIT_13
+
| FUSE_RESERVED_CALIB1
| 0x7000FBB4
+
| 0x7000FB08
 
|-
 
|-
| FUSE_SPARE_BIT_14
+
| FUSE_OPT_GPU_TPC0_DISABLE
| 0x7000FBB8
+
| 0x7000FB0C
 
|-
 
|-
| FUSE_SPARE_BIT_15
+
| FUSE_OPT_GPU_TPC0_DISABLE_CP1
| 0x7000FBBC
+
| 0x7000FB10
 
|-
 
|-
| FUSE_SPARE_BIT_16
+
| FUSE_OPT_CPU_DISABLE
| 0x7000FBC0
+
| 0x7000FB14
 
|-
 
|-
| FUSE_SPARE_BIT_17
+
| FUSE_OPT_CPU_DISABLE_CP1
| 0x7000FBC4
+
| 0x7000FB18
 
|-
 
|-
| FUSE_SPARE_BIT_18
+
| FUSE_TSENSOR10_CALIB
| 0x7000FBC8
+
| 0x7000FB1C
 
|-
 
|-
| FUSE_SPARE_BIT_19
+
| FUSE_TSENSOR10_CALIB_AUX
| 0x7000FBCC
+
| 0x7000FB20
 
|-
 
|-
| FUSE_SPARE_BIT_20
+
| FUSE_OPT_RAM_SVOP_DP
| 0x7000FBD0
+
| 0x7000FB24
 
|-
 
|-
| FUSE_SPARE_BIT_21
+
| FUSE_OPT_RAM_SVOP_PDP
| 0x7000FBD4
+
| 0x7000FB28
 
|-
 
|-
| FUSE_SPARE_BIT_22
+
| FUSE_OPT_RAM_SVOP_REG
| 0x7000FBD8
+
| 0x7000FB2C
 
|-
 
|-
| FUSE_SPARE_BIT_23
+
| FUSE_OPT_RAM_SVOP_SP
| 0x7000FBDC
+
| 0x7000FB30
 
|-
 
|-
| FUSE_SPARE_BIT_24
+
| FUSE_OPT_RAM_SVOP_SMPDP
| 0x7000FBE0
+
| 0x7000FB34
 
|-
 
|-
| FUSE_SPARE_BIT_25
+
| FUSE_OPT_GPU_TPC0_DISABLE_CP2
| 0x7000FBE4
+
| 0x7000FB38
 
|-
 
|-
| FUSE_SPARE_BIT_26
+
| FUSE_OPT_GPU_TPC1_DISABLE
| 0x7000FBE8
+
| 0x7000FB3C
 
|-
 
|-
| FUSE_SPARE_BIT_27
+
| FUSE_OPT_GPU_TPC1_DISABLE_CP1
| 0x7000FBEC
+
| 0x7000FB40
 
|-
 
|-
| FUSE_SPARE_BIT_28
+
| FUSE_OPT_GPU_TPC1_DISABLE_CP2
| 0x7000FBF0
+
| 0x7000FB44
 +
|-
 +
| FUSE_OPT_CPU_DISABLE_CP2
 +
| 0x7000FB48
 +
|-
 +
| FUSE_OPT_GPU_DISABLE_CP2
 +
| 0x7000FB4C
 +
|-
 +
| FUSE_USB_CALIB_EXT
 +
| 0x7000FB50
 
|-
 
|-
| FUSE_SPARE_BIT_29
+
| FUSE_RESERVED_FIELD
| 0x7000FBF4
+
| 0x7000FB54
 
|-
 
|-
| FUSE_SPARE_BIT_30
+
| FUSE_SPARE_REALIGNMENT_REG
| 0x7000FBF8
+
| 0x7000FB7C
 
|-
 
|-
| FUSE_SPARE_BIT_31
+
| FUSE_SPARE_BIT_0
| 0x7000FBFC
+
| 0x7000FB80
|}
  −
 
  −
==== FUSE_SKU_INFO ====
  −
Stores the SKU ID (must be 0x83).
  −
 
  −
==== FUSE_OPT_FT_REV ====
  −
Stores the FT (Final Test) revision.
  −
 
  −
Original launch units have this value set to 0xA0 (revision 5.0). The first batch of patched units have this value set to 0xC0 (revision 6.0). The second batch of patched units have this value set to 0xE0 (revision 7.0)
  −
 
  −
==== FUSE_FA ====
  −
Stores failure analysis mode.
  −
 
  −
==== FUSE_SOC_SPEEDO_1_CALIB ====
  −
Stores the bootrom patch version.
  −
 
  −
==== FUSE_RESERVED_ODM0 ====
  −
This stores an hardware ID.
  −
 
  −
==== FUSE_RESERVED_ODM1 ====
  −
This stores an hardware ID.
  −
 
  −
==== FUSE_RESERVED_ODM2 ====
  −
{| class="wikitable" border="1"
  −
!  Bits
  −
!  Description
   
|-
 
|-
| 0-4
+
| FUSE_SPARE_BIT_1
| [5.0.0+] Used as key generation (patched units only)
+
| 0x7000FB84
|}
  −
 
  −
This stores an hardware ID in original launch units, but in patched units it stores a single value (key generation).
  −
 
  −
==== FUSE_RESERVED_ODM3 ====
  −
This stores an hardware ID in original launch units, but in patched units it's empty.
  −
 
  −
==== FUSE_RESERVED_ODM4 ====
  −
{| class="wikitable" border="1"
  −
!  Bits
  −
!  Description
   
|-
 
|-
| 0-1
+
| [[#FUSE_SPARE_BIT_2|FUSE_SPARE_BIT_2]]
| Unit type (3 = debug; 0 = retail)
+
| 0x7000FB88
 
|-
 
|-
| 2
+
| [[#FUSE_SPARE_BIT_3|FUSE_SPARE_BIT_3]]
| Unknown config (must be 1 on retail)
+
| 0x7000FB8C
 +
|-
 +
| [[#FUSE_SPARE_BIT_4|FUSE_SPARE_BIT_4]]
 +
| 0x7000FB90
 +
|-
 +
| [[#FUSE_SPARE_BIT_5|FUSE_SPARE_BIT_5]]
 +
| 0x7000FB94
 
|-
 
|-
| [1.0.0-3.0.2] 3-5
+
| FUSE_SPARE_BIT_6
[4.0.0+] 3-7
+
| 0x7000FB98
| DRAM ID
   
|-
 
|-
| 8
+
| FUSE_SPARE_BIT_7
| Unknown config mask (must be 0 on retail)
+
| 0x7000FB9C
 
|-
 
|-
| 9
+
| FUSE_SPARE_BIT_8
| Unit type mask (0 = debug; 1 = retail)
+
| 0x7000FBA0
 
|-
 
|-
| 10
+
| FUSE_SPARE_BIT_9
| [3.0.0+] Kiosk mode (0 = retail; 1 = kiosk)
+
| 0x7000FBA4
 
|-
 
|-
| 11
+
| FUSE_SPARE_BIT_10
| [5.0.0+] Unit patch flag (0 = unpatched; 1 = patched)
+
| 0x7000FBA8
 
|-
 
|-
| 16-19
+
| FUSE_SPARE_BIT_11
| [4.0.0+] New unit type (0 = Erista; 1 = Mariko; 2 = Mariko Lite)
+
| 0x7000FBAC
|}
  −
 
  −
This stores some device configuration parameters.
  −
 
  −
==== FUSE_RESERVED_ODM6 ====
  −
This register returns the value programmed into index 0x3A of the fuse array.
  −
 
  −
==== FUSE_RESERVED_ODM7 ====
  −
This register returns the value programmed into index 0x3C of the fuse array.
  −
 
  −
==== FUSE_PUBLIC_KEY ====
  −
This stores the SHA256 hash of the 2048-bit RSA key expected at BCT+0x210.
  −
 
  −
==== FUSE_OPT_CP_REV ====
  −
Stores the CP (Chip Probing) revision.
  −
 
  −
Original launch units have this value set to 0xA0 (revision 5.0). Patched units have this value set to 0x103 (revision 8.3).
  −
 
  −
==== FUSE_PRIVATE_KEY ====
  −
This stores the 160-bit private key (128 bit SBK + 32-bit device key).
  −
Reads to these registers after the SBK is locked out produce all-FF output.
  −
 
  −
==== FUSE_RESERVED_SW ====
  −
{| class="wikitable" border="1"
  −
!  Bits
  −
!  Description
   
|-
 
|-
| 0-2
+
| FUSE_SPARE_BIT_12
| Boot device
+
| 0x7000FBB0
 
|-
 
|-
| 3
+
| FUSE_SPARE_BIT_13
| Skip device selection straps (0 = don't skip; 1 = skip)
+
| 0x7000FBB4
 
|-
 
|-
| 4
+
| FUSE_SPARE_BIT_14
| ENABLE_CHARGER_DETECT
+
| 0x7000FBB8
 
|-
 
|-
| 5
+
| FUSE_SPARE_BIT_15
| ENABLE_WATCHDOG
+
| 0x7000FBBC
 
|-
 
|-
| 6
+
| FUSE_SPARE_BIT_16
| Forced RCM two button mode (0 = Only VOLUME_UP; 1 = VOLUME_UP + HOME)
+
| 0x7000FBC0
 
|-
 
|-
| 7
+
| FUSE_SPARE_BIT_17
| RCM USB controller mode (0 = USB 2.0; 1 = XUSB)
+
| 0x7000FBC4
|}
  −
 
  −
This caches the value of the sw_reserved fuse from the hardware array.
  −
 
  −
Original launch units have the RCM USB controller mode set to USB 2.0, while the first batch of patched units have the RCM USB controller mode set to XUSB.
  −
 
  −
==== FUSE_PKC_DISABLE ====
  −
This caches the value of the pkc_disable fuse from the hardware array.
  −
 
  −
==== FUSE_SPARE_BIT_2 ====
  −
Stores part of the speedo fusing revision.
  −
 
  −
==== FUSE_SPARE_BIT_3 ====
  −
Stores part of the speedo fusing revision.
  −
 
  −
==== FUSE_SPARE_BIT_4 ====
  −
Stores part of the speedo fusing revision.
  −
 
  −
==== FUSE_SPARE_BIT_5 ====
  −
Must be non-zero on retail units, otherwise the first bootloader panics.
  −
On debug units it can be zero, which tells the bootloader to choose from two debug master key seeds. If set to non-zero on a debug unit, it tells the bootloader to choose from two master key seeds (with the second one being the retail master key seed).
  −
 
  −
[4.0.0+] This value is no longer used during boot.
  −
 
  −
== Bitmap ==
  −
The actual hardware fuses are stored in a bitmap and may be programmed through the fuse driver after enabling fuse programming.
  −
 
  −
Fuse numbers are relative to the start of the fuse bitmap where each element is a 4 byte word and has a redundant alias. A single fuse write operation must always write the same value to '''fuse_bitmap + ((fuse_number + 0) << 2)''' (PRIMARY_ALIAS) and '''fuse_bitmap + ((fuse_number + 1) << 2)''' (REDUNDANT_ALIAS). However, after offset 0x180 in the fuse bitmap, fuses no longer have a redundant alias.
  −
 
  −
Below is a list of common fuses used by Tegra devices (and applicable to the Switch).
  −
 
  −
{| class="wikitable" border="1"
  −
!  Name
  −
!  Number
  −
!  Redundant number
  −
!  Bits
   
|-
 
|-
| enable_fuse_program
+
| FUSE_SPARE_BIT_18
| 0
+
| 0x7000FBC8
| 1
  −
| 0
   
|-
 
|-
| disable_fuse_program
+
| FUSE_SPARE_BIT_19
| 0
+
| 0x7000FBCC
| 1
  −
| 1
   
|-
 
|-
| bypass_fuses
+
| FUSE_SPARE_BIT_20
| 0
+
| 0x7000FBD0
| 1
  −
| 2
   
|-
 
|-
| jtag_direct_access_disable
+
| FUSE_SPARE_BIT_21
| 0
+
| 0x7000FBD4
| 1
  −
| 3
   
|-
 
|-
| production_mode
+
| FUSE_SPARE_BIT_22
| 0
+
| 0x7000FBD8
| 1
  −
| 4
   
|-
 
|-
| jtag_secureid_valid
+
| FUSE_SPARE_BIT_23
| 0
+
| 0x7000FBDC
| 1
  −
| 5
   
|-
 
|-
| odm_lock
+
| FUSE_SPARE_BIT_24
| 0
+
| 0x7000FBE0
| 1
  −
| 6-9
   
|-
 
|-
| fa_mode
+
| FUSE_SPARE_BIT_25
| 0
+
| 0x7000FBE4
| 1
  −
| 10
   
|-
 
|-
| security_mode
+
| FUSE_SPARE_BIT_26
| 0
+
| 0x7000FBE8
| 1
  −
| 11
   
|-
 
|-
| arm_debug_dis
+
| FUSE_SPARE_BIT_27
| 0
+
| 0x7000FBEC
| 1
  −
| 12
   
|-
 
|-
| obs_dis
+
| FUSE_SPARE_BIT_28
| 0
+
| 0x7000FBF0
| 1
  −
| 13
   
|-
 
|-
| public_key0
+
| FUSE_SPARE_BIT_29
| 10
+
| 0x7000FBF4
| 11
  −
| 30-31
   
|-
 
|-
| public_key0
+
| FUSE_SPARE_BIT_30
| 12
+
| 0x7000FBF8
| 13
  −
| 0-29
   
|-
 
|-
| public_key1
+
| FUSE_SPARE_BIT_31
| 12
+
| 0x7000FBFC
| 13
+
|}
| 30-31
+
 
|-
+
==== FUSE_SKU_INFO ====
| public_key1
+
Stores the SKU ID (must be 0x83).
| 14
+
 
| 15
+
==== FUSE_OPT_FT_REV ====
| 0-29
+
Stores the FT (Final Test) revision.
|-
+
 
| public_key2
+
Original launch units have this value set to 0xA0 (revision 5.0). The first batch of patched units have this value set to 0xC0 (revision 6.0). The second batch of patched units have this value set to 0xE0 (revision 7.0)
| 14
+
 
| 15
+
==== FUSE_SOC_SPEEDO_1_CALIB ====
| 30-31
+
Stores the bootrom patch version.
 +
 
 +
==== FUSE_FA ====
 +
Stores failure analysis mode.
 +
 
 +
==== FUSE_PUBLIC_KEY ====
 +
Stores the SHA256 hash of the 2048-bit RSA key expected at BCT+0x210.
 +
 
 +
==== FUSE_OPT_CP_REV ====
 +
Stores the CP (Chip Probing) revision.
 +
 
 +
Original launch units have this value set to 0xA0 (revision 5.0). Patched units have this value set to 0x103 (revision 8.3).
 +
 
 +
==== FUSE_PRIVATE_KEY ====
 +
Stores the 160-bit private key (128 bit SBK + 32-bit device key).
 +
 
 +
Reads to these registers after the SBK is locked out produce all-FF output.
 +
 
 +
==== FUSE_RESERVED_SW ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| public_key2
+
| 0-2
| 16
+
| Boot device
| 17
  −
| 0-29
   
|-
 
|-
| public_key3
+
| 3
| 16
+
| Skip device selection straps
| 17
  −
| 30-31
   
|-
 
|-
| public_key3
+
| 4
| 18
+
| Enable charger detection
| 19
  −
| 0-29
   
|-
 
|-
| public_key4
+
| 5
| 18
+
| Enable watchdog
| 19
  −
| 30-31
   
|-
 
|-
| public_key4
+
| 6
| 20
+
| Forced RCM two button mode (0 = VOLUME_UP, 1 = VOLUME_UP + HOME)
| 21
  −
| 0-29
   
|-
 
|-
| public_key5
+
| 7
| 20
+
| RCM USB controller mode (0 = USB 2.0, 1 = XUSB)
| 21
+
|}
| 30-31
+
 
 +
Stores software reserved configuration values.
 +
 
 +
Original launch units have the RCM USB controller mode set to USB 2.0, while the first batch of patched units have the RCM USB controller mode set to XUSB.
 +
 
 +
==== FUSE_RESERVED_ODM0 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| public_key5
+
| 0-31
| 22
+
| OdmTestId0
| 23
+
|}
| 0-29
+
 
 +
==== FUSE_RESERVED_ODM1 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| public_key6
+
| 0-31
| 22
+
| OdmTestId1
| 23
+
|}
| 30-31
+
 
 +
==== FUSE_RESERVED_ODM2 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| public_key6
+
| 0-31
| 24
+
| OdmTestId2
| 25
+
|}
| 0-29
+
 
|-
+
[5.0.0+] If [[#FUSE_RESERVED_ODM4|FormatVersion]] is 1, this becomes:
| public_key7
+
 
| 24
+
{| class="wikitable" border="1"
| 25
+
!  Bits
| 30-31
+
!  Description
 
|-
 
|-
| public_key7
+
| 0-4
| 26
+
| DeviceUniqueKeyGeneration
| 27
  −
| 0-29
   
|-
 
|-
| private_key0
+
| 5-31
| 34
+
| Reserved
| 35
+
|}
| 12-31
+
 
 +
==== FUSE_RESERVED_ODM3 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| private_key0
+
| 0-31
| 36
+
| OdmTestId3
| 37
+
|}
| 0-11
+
 
|-
+
[5.0.0+] If [[#FUSE_RESERVED_ODM4|FormatVersion]] is 1, this becomes:
| private_key1
+
 
| 36
+
{| class="wikitable" border="1"
| 37
+
!  Bits
| 12-31
+
!  Description
 +
|-
 +
| 0-31
 +
| Reserved
 +
|}
 +
 
 +
==== FUSE_RESERVED_ODM4 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| private_key1
+
| 0-1
| 38
+
| HardwareState1
| 39
  −
| 0-11
   
|-
 
|-
| private_key2
+
| 2
| 38
+
| HardwareType1
| 39
  −
| 12-31
   
|-
 
|-
| private_key2
+
| [1.0.0-3.0.2] 3-5
| 40
+
[4.0.0+] 3-7
| 41
+
| DramId
| 0-11
   
|-
 
|-
| private_key3
+
| 8
| 40
+
| HardwareType2
| 41
  −
| 12-31
   
|-
 
|-
| private_key3
+
| 9
| 42
+
| HardwareState2
| 43
  −
| 0-11
   
|-
 
|-
| private_key4
+
| 10
| 42
+
| [3.0.0+] QuestState
| 43
  −
| 12-31
   
|-
 
|-
| private_key4
+
| 11
| 44
+
| [5.0.0+] FormatVersion
| 45
  −
| 0-11
   
|-
 
|-
| boot_device_info
+
| 16-19
| 44
+
| [4.0.0+] HardwareType3
| 45
+
|}
| 12-27
+
 
|-
+
Stores device configuration parameters.
| reserved_sw
+
 
| 44
+
==== FUSE_RESERVED_ODM5 ====
| 45
+
Empty and unused.
| 28-31
+
 
 +
==== FUSE_RESERVED_ODM6 ====
 +
Returns the value of the [[#reserved_odm6|reserved_odm6]] anti-downgrade fuse.
 +
 
 +
==== FUSE_RESERVED_ODM7 ====
 +
Returns the value of the [[#reserved_odm7|reserved_odm7]] anti-downgrade fuse.
 +
 
 +
==== FUSE_OPT_SEC_DEBUG_EN ====
 +
Controls the [[TSEC#TSEC_SCP_CTL_STAT|Falcon SCP]] debug mode.
 +
 
 +
==== FUSE_OPT_PRIV_SEC_EN ====
 +
Controls the [[TSEC#FALCON_SCTL|Falcon Light Secure]] feature.
 +
 
 +
==== FUSE_PKC_DISABLE ====
 +
Returns if public key crypto is used or not.
 +
 
 +
==== FUSE_ECO_RESERVE_0 ====
 +
Returns the chip unique AID.
 +
 
 +
==== FUSE_SPARE_BIT_2 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| reserved_sw
+
| 0
| 46
+
| Speedo fusing revision
| 47
+
|}
| 0-3
+
 
 +
==== FUSE_SPARE_BIT_3 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 
|-
 
|-
| reserved_odm0
+
| 0
| 46
+
| Speedo fusing revision
| 47
+
|}
| 5-31
+
 
 +
==== FUSE_SPARE_BIT_4 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| Speedo fusing revision
 +
|}
 +
 
 +
==== FUSE_SPARE_BIT_5 ====
 +
Must be non-zero on retail units, otherwise the first bootloader panics.
 +
On prototype units it can be zero, which tells the bootloader to choose from two pre-production master key seeds. If set to non-zero on a prototype unit, it tells the bootloader to choose from two master key seeds (with the second one being the same as the retail master key seed).
 +
 
 +
[4.0.0+] This value is no longer used during boot.
 +
 
 +
== Mariko ==
 +
Registers from 0x7000F800 to 0x7000F800 + 0x94 represent the actual fuse [[#Driver_2|driver]] which can be used to directly program the hardware fuse bitmap.
 +
 
 +
Registers from 0x7000F800 + 0x98 to 0x7000F800 + 0x3FC represent the fuse [[#Cache_2|cache]] which holds the sensed values of certain fuses.
 +
 
 +
=== Driver ===
 +
Same registers as in the Erista's fuse [[#Driver|driver]].
 +
 
 +
=== Cache ===
 +
{| class="wikitable" border="1"
 +
!  Name
 +
!  Address
 +
|-
 +
| FUSE_RESERVED_ODM8
 +
| 0x7000F898
 
|-
 
|-
| reserved_odm0
+
| FUSE_RESERVED_ODM9
| 48
+
| 0x7000F89C
| 49
  −
| 0-4
   
|-
 
|-
| reserved_odm1
+
| FUSE_RESERVED_ODM10
| 48
+
| 0x7000F8A0
| 49
  −
| 5-31
   
|-
 
|-
| reserved_odm1
+
| FUSE_RESERVED_ODM11
| 50
+
| 0x7000F8A4
| 51
  −
| 0-4
   
|-
 
|-
| reserved_odm2
+
| FUSE_RESERVED_ODM12
| 50
+
| 0x7000F8A8
| 51
+
|-
| 5-31
+
| FUSE_RESERVED_ODM13
 +
| 0x7000F8AC
 
|-
 
|-
| reserved_odm2
+
| FUSE_RESERVED_ODM14
| 52
+
| 0x7000F8B0
| 53
  −
| 0-4
   
|-
 
|-
| reserved_odm3
+
| FUSE_RESERVED_ODM15
| 52
+
| 0x7000F8B4
| 53
  −
| 5-31
   
|-
 
|-
| reserved_odm3
+
| FUSE_RESERVED_ODM16
| 54
+
| 0x7000F8B8
| 55
  −
| 0-4
   
|-
 
|-
| reserved_odm4
+
| FUSE_RESERVED_ODM17
| 54
+
| 0x7000F8BC
| 55
  −
| 5-31
   
|-
 
|-
| reserved_odm4
+
| FUSE_RESERVED_ODM18
| 56
+
| 0x7000F8C0
| 57
  −
| 0-4
   
|-
 
|-
| reserved_odm5
+
| FUSE_RESERVED_ODM19
| 56
+
| 0x7000F8C4
| 57
  −
| 5-31
   
|-
 
|-
| reserved_odm5
+
| FUSE_RESERVED_ODM20
| 58
+
| 0x7000F8C8
| 59
  −
| 0-4
   
|-
 
|-
| [[#reserved_odm6|reserved_odm6]]
+
| FUSE_RESERVED_ODM21
| 58
+
| 0x7000F8CC
| 59
  −
| 5-31
   
|-
 
|-
| [[#reserved_odm6|reserved_odm6]]
+
| FUSE_KEK00
| 60
+
| 0x7000F8D0
| 61
  −
| 0-4
   
|-
 
|-
| [[#reserved_odm7|reserved_odm7]]
+
| FUSE_KEK01
| 60
+
| 0x7000F8D4
| 61
  −
| 5-31
   
|-
 
|-
| [[#reserved_odm7|reserved_odm7]]
+
| FUSE_KEK02
| 62
+
| 0x7000F8D8
| 63
  −
| 0-4
   
|-
 
|-
| kfuse_privkey_ctrl
+
| FUSE_KEK03
| 64
+
| 0x7000F8DC
| 65
  −
| 13-14
   
|-
 
|-
| package_info
+
| FUSE_BEK00
| 64
+
| 0x7000F8E0
| 65
  −
| 15-18
   
|-
 
|-
| opt_vendor_code
+
| FUSE_BEK01
| 64
+
| 0x7000F8E4
| 65
  −
| 19-22
   
|-
 
|-
| opt_fab_code
+
| FUSE_BEK02
| 64
+
| 0x7000F8E8
| 65
  −
| 23-28
   
|-
 
|-
| opt_lot_code_0
+
| FUSE_BEK03
| 64
+
| 0x7000F8EC
| 65
  −
| 29-31
   
|-
 
|-
| opt_lot_code_0
+
|  
| 66
+
| 0x7000F8F0
| 67
  −
| 0-28
   
|-
 
|-
| opt_lot_code_1
+
|  
| 66
+
| 0x7000F8F4
| 67
  −
| 29-31
   
|-
 
|-
| opt_lot_code_1
+
|  
| 68
+
| 0x7000F8F8
| 69
  −
| 0-24
   
|-
 
|-
| opt_wafer_id
+
|  
| 68
+
| 0x7000F8FC
| 69
  −
| 25-30
   
|-
 
|-
| opt_x_coordinate
+
| FUSE_PRODUCTION_MODE
| 68
+
| 0x7000F900
| 69
  −
| 31
   
|-
 
|-
| opt_x_coordinate
+
| FUSE_JTAG_SECUREID_VALID
| 70
+
| 0x7000F904
| 71
  −
| 0-7
   
|-
 
|-
| opt_y_coordinate
+
| FUSE_ODM_LOCK
| 70
+
| 0x7000F908
| 71
+
|-
| 8-16
+
| FUSE_OPT_OPENGL_EN
 +
| 0x7000F90C
 
|-
 
|-
| opt_sec_debug_en
+
| FUSE_SKU_INFO
| 70
+
| 0x7000F910
| 71
  −
| 17
   
|-
 
|-
| opt_ops_reserved
+
| FUSE_CPU_SPEEDO_0_CALIB
| 70
+
| 0x7000F914
| 71
  −
| 18-23
   
|-
 
|-
| sata_calib
+
| FUSE_CPU_IDDQ_CALIB
| 70
+
| 0x7000F918
| 71
  −
| 24-25
   
|-
 
|-
| opt_priv_sec_en
+
| FUSE_RESERVED_ODM22
| 90
+
| 0x7000F91C
| 91
  −
| 8
   
|-
 
|-
| pkc_disable
+
| FUSE_RESERVED_ODM23
| 90
+
| 0x7000F920
| 91
+
|-
| 9
+
| FUSE_RESERVED_ODM24
 +
| 0x7000F924
 
|-
 
|-
| fuse2tsec_debug_disable
+
| FUSE_OPT_FT_REV
| 90
+
| 0x7000F928
| 91
  −
| 10
   
|-
 
|-
| secure_provision_index
+
| FUSE_CPU_SPEEDO_1_CALIB
| 90
+
| 0x7000F92C
| 91
  −
| 24-27
   
|-
 
|-
| secure_provision_info
+
| FUSE_CPU_SPEEDO_2_CALIB
| 90
+
| 0x7000F930
| 91
  −
| 28-29
   
|-
 
|-
| aid
+
| FUSE_SOC_SPEEDO_0_CALIB
| 103
+
| 0x7000F934
| None
  −
| 0-31
   
|-
 
|-
| [[#irom_patch|irom_patch]]
+
| FUSE_SOC_SPEEDO_1_CALIB
| 114
+
| 0x7000F938
| None
+
|-
| Variable
+
| FUSE_SOC_SPEEDO_2_CALIB
|}
+
| 0x7000F93C
 
+
|-
=== reserved_odm6 ===
+
| FUSE_SOC_IDDQ_CALIB
Used for anti-downgrade control.
+
| 0x7000F940
 
+
|-
=== reserved_odm7 ===
+
| FUSE_RESERVED_ODM25
Used for anti-downgrade control.
+
| 0x7000F944
 
+
|-
=== irom_patch ===
+
| FUSE_FA
Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse bitmap 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.
+
| 0x7000F948
 
+
|-
The following represents the patch data dumped from a Switch console:
+
| FUSE_RESERVED_PRODUCTION
<syntaxhighlight>
+
| 0x7000F94C
RAM:00000000 ; =============== S U B R O U T I N E =======================================
+
|-
RAM:00000000
+
| FUSE_HDMI_LANE0_CALIB
RAM:00000000
+
| 0x7000F950
RAM:00000000 irom_svc_dispatch
+
|-
RAM:00000000  STMFD  SP!, {R0-R2}                  ; ipatches (new):
+
| FUSE_HDMI_LANE1_CALIB
RAM:00000000                                        ;  0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
+
| 0x7000F954
RAM:00000000                                        ;  1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
+
|-
RAM:00000000                                        ;  2 3797df26    6f2e    df26 : svc #0x26 (offset 0x94)
+
| FUSE_HDMI_LANE2_CALIB
RAM:00000000                                        ;  3 3b4d2100    769a    2100 : movs r1, #0x00
+
| 0x7000F958
RAM:00000000                                        ;  4  42bdf2c      856    df2c : svc #0x2c (offset 0xa0)
+
|-
RAM:00000000                                        ;  5 37aadf42    6f54    df42 : svc #0x42 (offset 0xcc)
+
| FUSE_HDMI_LANE3_CALIB
RAM:00000000                                        ;  6  972df4b    12e4    df4b : svc #0x4b (offset 0xde)
+
| 0x7000F95C
RAM:00000000                                        ;  7 2293df54    4526    df54 : svc #0x54 (offset 0xf0)
+
|-
RAM:00000000                                        ;  8 21fadf5d    43f4    df5d : svc #0x5d (offset 0x102)
+
| FUSE_ENCRYPTION_RATE
RAM:00000000                                        ;  9 bba2ac57    17744    ac57 : data
+
| 0x7000F960
RAM:00000000                                        ; 10 bbac3d19    17758    3d19 : data
+
|-
RAM:00000000                                        ; 11 1e952001    3d2a    2001 : movs r0, #0x01
+
| FUSE_PUBLIC_KEY0
RAM:00000000                                        ;
+
| 0x7000F964
RAM:00000000                                        ; ipatches (old):
+
|-
RAM:00000000                                        ;  0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
+
| FUSE_PUBLIC_KEY1
RAM:00000000                                        ;  1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
+
| 0x7000F968
RAM:00000000                                        ;  2 3797df26    6f2e    df26 : svc #0x26 (offset 0x94)
+
|-
RAM:00000000                                        ;  3 7d9e2000    fb3c    2000 : movs r0, #0x00
+
| FUSE_PUBLIC_KEY2
RAM:00000000                                        ;  4  42bdf2c      856    df2c : svc #0x2c (offset 0xa0)
+
| 0x7000F96C
RAM:00000000                                        ;  5 37aadf42    6f54    df42 : svc #0x42 (offset 0xcc)
+
|-
RAM:00000000                                        ;  6  972df4b    12e4    df4b : svc #0x4b (offset 0xde)
+
| FUSE_PUBLIC_KEY3
RAM:00000000                                        ;  7 2293df54    4526    df54 : svc #0x54 (offset 0xf0)
+
| 0x7000F970
RAM:00000000                                        ;  8 21fadf5d    43f4    df5d : svc #0x5d (offset 0x102)
+
|-
RAM:00000000                                        ;  9 bba2ac57    17744    ac57 : data
+
| FUSE_PUBLIC_KEY4
RAM:00000000                                        ; 10 bbac3d19    17758    3d19 : data
+
| 0x7000F974
RAM:00000000                                        ; 11 1e952001    3d2a    2001 : movs r0, #0x01
+
|-
RAM:00000004  MOV    R2, LR
+
| FUSE_PUBLIC_KEY5
RAM:00000008  SUB    R2, R2, #2
+
| 0x7000F978
RAM:0000000C  LDR    R2, [R2]
+
|-
RAM:00000010  AND    R2, R2, #0xFF
+
| FUSE_PUBLIC_KEY6
RAM:00000014  MOV    R2, R2,LSL#1
+
| 0x7000F97C
RAM:00000018  LDR    R0, =0x1007B0
+
|-
RAM:0000001C  LDR    R1, =0x1007F8
+
| FUSE_PUBLIC_KEY7
RAM:00000020  SUB    R1, R1, R0
+
| 0x7000F980
RAM:00000024  LDR    R0, =0x40004C30
+
|-
RAM:00000028  ADD    R0, R0, R1
+
| FUSE_TSENSOR1_CALIB
RAM:0000002C  ADD    R2, R2, R0
+
| 0x7000F984
RAM:00000030  ORR    R2, R2, #1
+
|-
RAM:00000034  LDMFD  SP!, {R0,R1}
+
| FUSE_TSENSOR2_CALIB
RAM:00000038  BX      R2
+
| 0x7000F988
RAM:00000038 ; End of function irom_svc_dispatch
+
|-
RAM:00000038
+
| FUSE_OPT_SECURE_SCC_DIS
RAM:00000038 ; ---------------------------------------------------------------------------
+
| 0x7000F98C
RAM:0000003C dword_3C DCD 0x1007B0                  ; DATA XREF: irom_svc_dispatch+18↑r
+
|-
RAM:00000040 dword_40 DCD 0x1007F8                  ; DATA XREF: irom_svc_dispatch+1C↑r
+
| FUSE_OPT_CP_REV
RAM:00000044 dword_44 DCD 0x40004C30                ; DATA XREF: irom_svc_dispatch+24↑r
+
| 0x7000F990
RAM:00000048  CODE16
+
|-
RAM:00000048
+
| FUSE_OPT_PFG
RAM:00000048 ; =============== S U B R O U T I N E =======================================
+
| 0x7000F994
RAM:00000048
+
|-
RAM:00000048
+
| FUSE_TSENSOR0_CALIB
RAM:00000048 sub_48
+
| 0x7000F998
RAM:00000048  MOVS    R2, #0                        ; 0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
+
|-
RAM:0000004A  MVNS    R2, R2
+
| FUSE_FIRST_BOOTROM_PATCH_SIZE
RAM:0000004C  LDR    R1, =0x60006410
+
| 0x7000F99C
RAM:0000004E  STR    R2, [R1,#0x30]
+
|-
RAM:00000050  STR    R2, [R1,#0x38]
+
| FUSE_SECURITY_MODE
RAM:00000052  LDR    R1, =0x600060F8
+
| 0x7000F9A0
RAM:00000054  STR    R2, [R1]
+
|-
RAM:00000056  STR    R2, [R1,#4]
+
| FUSE_PRIVATE_KEY0
RAM:00000058  LDR    R1, =0x60006284
+
| 0x7000F9A4
RAM:0000005A  STR    R2, [R1]
+
|-
RAM:0000005C  STR    R2, [R1,#0x18]
+
| FUSE_PRIVATE_KEY1
RAM:0000005E  ADDS    R1, #0x80
+
| 0x7000F9A8
RAM:00000060  ADDS    R1, #0x1C
+
|-
RAM:00000062  STR    R2, [R1]
+
| FUSE_PRIVATE_KEY2
RAM:00000064  STR    R2, [R1,#8]
+
| 0x7000F9AC
RAM:00000066  STR    R2, [R1,#0x10]
+
|-
RAM:00000068  ADDS    R1, #0x80
+
| FUSE_PRIVATE_KEY3
RAM:0000006A  STR    R2, [R1]
+
| 0x7000F9B0
RAM:0000006C  STR    R2, [R1,#4]
+
|-
RAM:0000006E  LDR    R1, =0x60006554
+
| FUSE_PRIVATE_KEY4
RAM:00000070  STR    R2, [R1]
+
| 0x7000F9B4
RAM:00000072  MOVS    R2, #0xA0000000
+
|-
RAM:00000076  LDR    R1, =0x60006148
+
| FUSE_ARM_JTAG_DIS
RAM:00000078  STR    R2, [R1]
+
| 0x7000F9B8
RAM:0000007A  ADDS    R1, #0x38 ; '8'
+
|-
RAM:0000007C  STR    R2, [R1]
+
| FUSE_BOOT_DEVICE_INFO
RAM:0000007E  MOVS    R2, #0xE0000000
+
| 0x7000F9BC
RAM:00000082  LDR    R1, =0x600066A0
+
|-
RAM:00000084  STR    R2, [R1]
+
| FUSE_RESERVED_SW
RAM:00000086  MOVS    R1, #0
+
| 0x7000F9C0
RAM:00000088  MOVS    R0, #0xE
+
|-
RAM:0000008A  B      pop_r2_mov_pc_lr
+
| FUSE_OPT_VP9_DISABLE
RAM:0000008A ; End of function sub_48
+
| 0x7000F9C4
RAM:0000008A
+
|-
RAM:0000008C
+
| FUSE_RESERVED_ODM0
RAM:0000008C ; =============== S U B R O U T I N E =======================================
+
| 0x7000F9C8
RAM:0000008C
+
|-
RAM:0000008C
+
| FUSE_RESERVED_ODM1
RAM:0000008C sub_8C
+
| 0x7000F9CC
RAM:0000008C  LDR    R0, [R1,#0x18]                ; 1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
+
|-
RAM:0000008E  MOVS    R2, #1
+
| FUSE_RESERVED_ODM2
RAM:00000090  ORRS    R0, R2
+
| 0x7000F9D0
RAM:00000092  B      pop_r2_mov_pc_lr
+
|-
RAM:00000092 ; End of function sub_8C
+
| FUSE_RESERVED_ODM3
RAM:00000092
+
| 0x7000F9D4
RAM:00000094
+
|-
RAM:00000094 ; =============== S U B R O U T I N E =======================================
+
| FUSE_RESERVED_ODM4
RAM:00000094
+
| 0x7000F9D8
RAM:00000094
+
|-
RAM:00000094 sub_94
+
| FUSE_RESERVED_ODM5
RAM:00000094  LDR    R2, [R4,#0x50]                ; 2 3797df26    6f2e    df26 : svc #0x26 (offset 0x94)
+
| 0x7000F9DC
RAM:00000096  ADDS    R2, R2, #2
+
|-
RAM:00000098  STR    R2, [R4,#0x50]
+
| FUSE_RESERVED_ODM6
RAM:0000009A  SUBS    R1, #0x80
+
| 0x7000F9E0
RAM:0000009C  STR    R1, [R4,#0x34]
+
|-
RAM:0000009E  B      pop_r2_mov_pc_lr
+
| FUSE_RESERVED_ODM7
RAM:0000009E ; End of function sub_94
+
| 0x7000F9E4
RAM:0000009E
+
|-
RAM:000000A0
+
| FUSE_OBS_DIS
RAM:000000A0 ; =============== S U B R O U T I N E =======================================
+
| 0x7000F9E8
RAM:000000A0
+
|-
RAM:000000A0
+
|
RAM:000000A0 sub_A0
+
| 0x7000F9EC
RAM:000000A0
+
|-
RAM:000000A0 ; FUNCTION CHUNK AT RAM:00000148 SIZE 00000004 BYTES
+
| FUSE_USB_CALIB
RAM:000000A0
+
| 0x7000F9F0
RAM:000000A0  MOVS    R0, #0x70000000              ; 4  42bdf2c      856    df2c : svc #0x2c (offset 0xa0)
+
|-
RAM:000000A4  LDR    R6, =dword_7000EF14
+
| FUSE_SKU_DIRECT_CONFIG
RAM:000000A6  LDR    R2, =dword_7000E5B4
+
| 0x7000F9F4
RAM:000000A8  LDR    R2, [R2]
+
|-
RAM:000000AA  CMP    R2, #0
+
| FUSE_KFUSE_PRIVKEY_CTRL
RAM:000000AC  BEQ    loc_B4
+
| 0x7000F9F8
RAM:000000AE  LDR    R2, [R6]
+
|-
RAM:000000B0  STR    R2, [R0,#8]
+
| FUSE_PACKAGE_INFO
RAM:000000B2  B      loc_BC
+
| 0x7000F9FC
RAM:000000B4 ; ---------------------------------------------------------------------------
+
|-
RAM:000000B4
+
| FUSE_OPT_VENDOR_CODE
RAM:000000B4 loc_B4                                  ; CODE XREF: sub_A0+C↑j
+
| 0x7000FA00
RAM:000000B4  LDR    R2, [R0,#8]
+
|-
RAM:000000B6  LSRS    R0, R0, #0x12
+
| FUSE_OPT_FAB_CODE
RAM:000000B8  ORRS    R2, R0
+
| 0x7000FA04
RAM:000000BA  STR    R2, [R6]
+
|-
RAM:000000BC
+
| FUSE_OPT_LOT_CODE_0
RAM:000000BC loc_BC                                  ; CODE XREF: sub_A0+12↑j
+
| 0x7000FA08
RAM:000000BC  LDR    R6, =dword_7000E9C0
+
|-
RAM:000000BE  LDR    R0, [R6]
+
| FUSE_OPT_LOT_CODE_1
RAM:000000C0  MOVS    R2, #0x4000
+
| 0x7000FA0C
RAM:000000C4  ORRS    R2, R0
+
|-
RAM:000000C6  STR    R2, [R6]
+
| FUSE_OPT_WAFER_ID
RAM:000000C8  LDR    R0, [R5,#0x10]
+
| 0x7000FA10
RAM:000000CA  B      pop_r2_mov_pc_lr
+
|-
RAM:000000CA ; End of function sub_A0
+
| FUSE_OPT_X_COORDINATE
RAM:000000CA
+
| 0x7000FA14
RAM:000000CC
+
|-
RAM:000000CC ; =============== S U B R O U T I N E =======================================
+
| FUSE_OPT_Y_COORDINATE
RAM:000000CC
+
| 0x7000FA18
RAM:000000CC
+
|-
RAM:000000CC sub_CC
+
| FUSE_OPT_SEC_DEBUG_EN
RAM:000000CC  MOVS    R2, #0xF000000                ; 5 37aadf42    6f54    df42 : svc #0x42 (offset 0xcc)
+
| 0x7000FA1C
RAM:000000D0  BICS    R1, R2
+
|-
RAM:000000D2  STR    R1, [R4,#0x10]
+
| FUSE_OPT_OPS_RESERVED
RAM:000000D4  LDR    R1, [R4,#0x50]
+
| 0x7000FA20
RAM:000000D6  MOVS    R2, #7
+
|-
RAM:000000D8  BICS    R1, R2
+
|
RAM:000000DA  STR    R1, [R4,#0x50]
+
| 0x7000FA24
RAM:000000DC  B      pop_r2_mov_pc_lr
+
|-
RAM:000000DC ; End of function sub_CC
+
| FUSE_GPU_IDDQ_CALIB
RAM:000000DC
+
| 0x7000FA28
RAM:000000DE
+
|-
RAM:000000DE ; =============== S U B R O U T I N E =======================================
+
| FUSE_TSENSOR3_CALIB
RAM:000000DE
+
| 0x7000FA2C
RAM:000000DE
+
|-
RAM:000000DE sub_DE
+
| FUSE_CLOCK_BONDOUT0
RAM:000000DE  LDR    R2, =dword_7000FA9C          ; 6  972df4b    12e4    df4b : svc #0x4b (offset 0xde)
+
| 0x7000FA30
RAM:000000E0  LDR    R2, [R2]
+
|-
RAM:000000E2  LSRS    R2, R2, #8
+
| FUSE_CLOCK_BONDOUT1
RAM:000000E4  LSLS    R2, R2, #1
+
| 0x7000FA34
RAM:000000E6  LDR    R1, [R4]
+
|-
RAM:000000E8  BICS    R1, R2
+
| FUSE_RESERVED_ODM26
RAM:000000EA  STR    R1, [R4]
+
| 0x7000FA38
RAM:000000EC  CMP    R0, #0
+
|-
RAM:000000EE  B      pop_r2_mov_pc_lr
+
| FUSE_RESERVED_ODM27
RAM:000000EE ; End of function sub_DE
+
| 0x7000FA3C
RAM:000000EE
+
|-
RAM:000000F0
+
| [[#FUSE_RESERVED_ODM28|FUSE_RESERVED_ODM28]]
RAM:000000F0 ; =============== S U B R O U T I N E =======================================
+
| 0x7000FA40
RAM:000000F0
+
|-
RAM:000000F0
+
| FUSE_OPT_SAMPLE_TYPE
RAM:000000F0 sub_F0
+
| 0x7000FA44
RAM:000000F0
+
|-
RAM:000000F0 arg_0=  0
+
| FUSE_OPT_SUBREVISION
RAM:000000F0
+
| 0x7000FA48
RAM:000000F0  LDR    R0, =0x400049F0              ; 7 2293df54    4526    df54 : svc #0x54 (offset 0xf0)
+
|-
RAM:000000F2  LDR    R2, [R0]
+
| FUSE_OPT_SW_RESERVED_0
RAM:000000F4  STR    R2, [SP,#arg_0]
+
| 0x7000FA4C
RAM:000000F6  LDR    R0, =0x40010000
+
|-
RAM:000000F8  LSRS    R2, R2, #17
+
| FUSE_OPT_SW_RESERVED_1
RAM:000000FA  BEQ    pop_r2_mov_pc_lr              ; if ([0x400049F0] >> 17) == 0) {
+
| 0x7000FA50
RAM:000000FA                                        ;  r2 = [0x400049F0];
+
|-
RAM:000000FA                                        ; } else {
+
| FUSE_TSENSOR4_CALIB
RAM:000000FC  LDR    R0, =APBDEV_PMC_CNTRL_0
+
| 0x7000FA54
RAM:000000FE  STR    R4, [R0]                      ;  write APBDEV_PMC_CNTRL
+
|-
RAM:00000100
+
| FUSE_TSENSOR5_CALIB
RAM:00000100 loc_100                                ; CODE XREF: sub_F0:loc_100↓j
+
| 0x7000FA58
RAM:00000100  B      loc_100                      ;  hang
+
|-
RAM:00000100 ; End of function sub_F0                ; }
+
| FUSE_TSENSOR6_CALIB
RAM:00000100
+
| 0x7000FA5C
RAM:00000102
+
|-
RAM:00000102 ; =============== S U B R O U T I N E =======================================
+
| FUSE_TSENSOR7_CALIB
RAM:00000102
+
| 0x7000FA60
RAM:00000102
+
|-
RAM:00000102 sub_102
+
| FUSE_OPT_PRIV_SEC_EN
RAM:00000102
+
| 0x7000FA64
RAM:00000102 arg_0=  0
+
|-
RAM:00000102
+
| [[#FUSE_BOOT_SECURITY_INFO|FUSE_BOOT_SECURITY_INFO]]
RAM:00000102  LDR    R2, =0x40010220              ; 8 21fadf5d    43f4    df5d : svc #0x5d (offset 0x102)
+
| 0x7000FA68
RAM:00000104  STR    R2, [SP,#arg_0]              ; set r2 retval = [0x40010220]
+
|-
RAM:00000106  LDR    R2, [R2,#0x18]
+
|
RAM:00000108  ADDS    R0, #0xFC
+
| 0x7000FA6C
RAM:0000010A  STR    R2, [R0,#0x1C]                ; [r0+0x118] = [0x40010220 + 0x18]
+
|-
RAM:0000010C  B      pop_r2_mov_pc_lr
+
|
RAM:0000010C ; End of function sub_102
+
| 0x7000FA70
RAM:0000010C
+
|-
RAM:0000010C ; ---------------------------------------------------------------------------
+
|
RAM:0000010E  DCB    0
+
| 0x7000FA74
RAM:0000010F  DCB    0
+
|-
RAM:00000110 off_110 DCD 0x60006410                  ; DATA XREF: sub_48+4↑r
+
|
RAM:00000114 off_114 DCD 0x600060F8                  ; DATA XREF: sub_48+A↑r
+
| 0x7000FA78
RAM:00000118 off_118 DCD 0x60006284                  ; DATA XREF: sub_48+10↑r
+
|-
RAM:0000011C off_11C DCD 0x60006554                  ; DATA XREF: sub_48+26↑r
+
| FUSE_FUSE2TSEC_DEBUG_DISABLE
RAM:00000120 off_120 DCD 0x60006148                  ; DATA XREF: sub_48+2E↑r
+
| 0x7000FA7C
RAM:00000124 off_124 DCD 0x600066A0                  ; DATA XREF: sub_48+3A↑r
+
|-
RAM:00000128 off_128 DCD dword_7000EF14              ; DATA XREF: sub_A0+4↑r
+
| FUSE_TSENSOR_COMMON
RAM:0000012C off_12C DCD dword_7000E5B4              ; DATA XREF: sub_A0+6↑r
+
| 0x7000FA80
RAM:00000130 off_130 DCD dword_7000E9C0              ; DATA XREF: sub_A0:loc_BC↑r
+
|-
RAM:00000134 off_134 DCD dword_7000FA9C              ; DATA XREF: sub_DE↑r
+
| FUSE_OPT_CP_BIN
RAM:00000138 off_138 DCD 0x400049F0                  ; DATA XREF: sub_F0↑r
+
| 0x7000FA84
RAM:0000013C dword_13C DCD 0x40010000                ; DATA XREF: sub_F0+6↑r
+
|-
RAM:00000140 off_140 DCD APBDEV_PMC_CNTRL_0          ; DATA XREF: sub_F0+C↑r
+
| FUSE_OPT_GPU_DISABLE
RAM:00000144 off_144 DCD 0x40010220                  ; DATA XREF: sub_102↑r
+
| 0x7000FA88
RAM:00000148 ; ---------------------------------------------------------------------------
+
|-
RAM:00000148 ; START OF FUNCTION CHUNK FOR sub_A0
+
| FUSE_OPT_FT_BIN
RAM:00000148
+
| 0x7000FA8C
RAM:00000148 pop_r2_mov_pc_lr                        ; CODE XREF: sub_48+42↑j
+
|-
RAM:00000148                                        ; sub_8C+6↑j ...
+
| FUSE_OPT_DONE_MAP
RAM:00000148  POP    {R2}
+
| 0x7000FA90
RAM:0000014A  MOV    PC, LR
+
|-
RAM:0000014A ; END OF FUNCTION CHUNK FOR sub_A0
+
| FUSE_RESERVED_ODM29
</syntaxhighlight>
+
| 0x7000FA94
 
+
|-
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices.
+
| FUSE_APB2JTAG_DISABLE
 
+
| 0x7000FA98
==== IROM patch 0 ====
+
|-
This patch configures clock enables and clock gate overrides for new hardware.
+
| FUSE_ODM_INFO
 
+
| 0x7000FA9C
<syntaxhighlight lang="c">
+
|-
u32 CLK_ENB_H_SET = 0x60006328;
+
| FUSE_ARM_CRYPT_DE_FEATURE
u32 CLK_ENB_L_SET = 0x60006320;
+
| 0x7000FAA8
u32 CLK_ENB_U_SET = 0x60006330;
+
|-
u32 CLK_ENB_V_SET = 0x60006440;
+
|
u32 CLK_ENB_W_SET = 0x60006448;
+
| 0x7000FAB0
u32 CLK_ENB_X_SET = 0x60006284;
+
|-
u32 CLK_ENB_Y_SET = 0x6000629C;
+
|
u32 LVL2_CLK_GATE_OVRA = 0x600060F8;
+
| 0x7000FAB4
u32 LVL2_CLK_GATE_OVRB = 0x600060FC;
+
|-
u32 LVL2_CLK_GATE_OVRC = 0x600063A0;
+
|
u32 LVL2_CLK_GATE_OVRD = 0x600063A4;
+
| 0x7000FAB8
u32 LVL2_CLK_GATE_OVRE = 0x60006554;
+
|-
u32 CLK_SOURCE_VI = 0x60006148;
+
|
u32 CLK_SOURCE_HOST1X = 0x60006180;
+
| 0x7000FABC
u32 CLK_SOURCE_NVENC = 0x600066A0;
+
|-
 
+
| FUSE_WOA_SKU_FLAG
// Set all clock enables and overrides
+
| 0x7000FAC0
*(u32 *)CLK_ENB_V_SET = 0xFFFFFFFF;
+
|-
*(u32 *)CLK_ENB_W_SET = 0xFFFFFFFF;
+
| FUSE_ECO_RESERVE_1
*(u32 *)LVL2_CLK_GATE_OVRA = 0xFFFFFFFF;
+
| 0x7000FAC4
*(u32 *)LVL2_CLK_GATE_OVRB = 0xFFFFFFFF;
+
|-
*(u32 *)CLK_ENB_X_SET = 0xFFFFFFFF;
+
| FUSE_GCPLEX_CONFIG_FUSE
*(u32 *)CLK_ENB_Y_SET = 0xFFFFFFFF;
+
| 0x7000FAC8
*(u32 *)CLK_ENB_L_SET = 0xFFFFFFFF;
+
|-
*(u32 *)CLK_ENB_H_SET = 0xFFFFFFFF;
+
| FUSE_PRODUCTION_MONTH
*(u32 *)CLK_ENB_U_SET = 0xFFFFFFFF;
+
| 0x7000FACC
*(u32 *)LVL2_CLK_GATE_OVRC = 0xFFFFFFFF;
+
|-
*(u32 *)LVL2_CLK_GATE_OVRD = 0xFFFFFFFF;
+
| FUSE_RAM_REPAIR_INDICATOR
*(u32 *)LVL2_CLK_GATE_OVRE = 0xFFFFFFFF;
+
| 0x7000FAD0
 
+
|-
// Set VI, HOST1X and NVENC clock sources to CLK_M
+
| FUSE_TSENSOR9_CALIB
*(u32 *)CLK_SOURCE_VI = 0xA0000000;
+
| 0x7000FAD4
*(u32 *)CLK_SOURCE_HOST1X = 0xA0000000;
+
|-
*(u32 *)CLK_SOURCE_NVENC = 0xE0000000;
+
| FUSE_VMIN_CALIBRATION
 
+
| 0x7000FADC
/*
+
|-
    Untranslated instructions:
+
| FUSE_AGING_SENSOR_CALIBRATION
 
+
| 0x7000FAE0
    MOVS    R1, #0
+
|-
    MOVS    R0, #0xE
+
| FUSE_DEBUG_AUTHENTICATION
*/
+
| 0x7000FAE4
+
|-
return;
+
| FUSE_SECURE_PROVISION_INDEX
</syntaxhighlight>
+
| 0x7000FAE8
 
+
|-
==== IROM patch 1 ====
+
| FUSE_SECURE_PROVISION_INFO
This patch is a bugfix.
+
| 0x7000FAEC
 
+
|-
LP0 resume code expects APBDEV_PMC_SCRATCH190_0 to be set to 0x01, but the bootrom didn't set it.
+
| FUSE_OPT_GPU_DISABLE_CP1
 
+
| 0x7000FAF0
<syntaxhighlight lang="c">
+
|-
u32 APBDEV_PMC_SCRATCH190_0 = 0x7000EC18;
+
| FUSE_SPARE_ENDIS
u32 pmc_scratch190_val = *(u32 *)APBDEV_PMC_SCRATCH190_0;
+
| 0x7000FAF4
+
|-
return (pmc_scratch190_val | 0x01);
+
| FUSE_ECO_RESERVE_0
</syntaxhighlight>
+
| 0x7000FAF8
 
+
|-
==== IROM patch 2 ====
+
| FUSE_RESERVED_CALIB0
This patch adjusts USB configurations.
+
| 0x7000FB04
 
+
|-
<syntaxhighlight lang="c">
+
| FUSE_RESERVED_CALIB1
u32 USB1_UTMIP_SPARE_CFG0_0 = 0x7D000834;
+
| 0x7000FB08
u32 USB1_UTMIP_BIAS_CFG2_0 = 0x7D000850;
+
|-
+
| FUSE_OPT_GPU_TPC0_DISABLE
// Increase UTMIP_HSSQUELCH_LEVEL_NEW by 0x02
+
| 0x7000FB0C
*(u32 *)USB1_UTMIP_BIAS_CFG2_0 += 0x02;
+
|-
 
+
| FUSE_OPT_GPU_TPC0_DISABLE_CP1
// Clear FUSE_HS_IREF_CAP_CFG
+
| 0x7000FB10
*(u32 *)USB1_UTMIP_SPARE_CFG0_0 = ((*(u32 *)USB1_UTMIP_SPARE_CFG0_0 & ~(0x118)) - 0x80);
+
|-
+
| FUSE_OPT_CPU_DISABLE
return;
+
| 0x7000FB14
</syntaxhighlight>
+
|-
 
+
| FUSE_OPT_CPU_DISABLE_CP1
==== IROM patch 3 ====
+
| 0x7000FB18
This patch ensures that waiting on PRC_PENDING from the XUSB_DEV register T_XUSB_DEV_XHCI_PORTSC never fails.
+
|-
 
+
| FUSE_TSENSOR10_CALIB
In the second batch of patched units ([[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]] set to revision 7.0) this patch has been replaced with a fix for [[Switch_System_Flaws#Hardware|CVE-2018-6242]] (arbitrary copy when handling USB control requests in RCM). By setting R1 to 0 at address 0x0010769A in the bootrom, the upper 16 bits of the USB control request's wLength field are cleared out, effectively limiting the request's size to a maximum of 255 bytes.
+
| 0x7000FB1C
 
+
|-
==== IROM patch 4 ====
+
| FUSE_TSENSOR10_CALIB_AUX
This patch allows backing up and restoring strapping options for warmboot.
+
| 0x7000FB20
 
+
|-
<syntaxhighlight lang="c">
+
|
u32 APBDEV_PMC_SCRATCH0_0 = 0x7000E450;
+
| 0x7000FB24
u32 APBDEV_PMC_RST_STATUS_0 = 0x7000E5B4;
+
|-
u32 APBDEV_PMC_SEC_DISABLE8_0 = 0x7000E9C0;
+
|
u32 APBDEV_PMC_SECURE_SCRATCH111_0 = 0x7000EF14;
+
| 0x7000FB28
u32 APB_MISC_PP_STRAPPING_OPT_A_0 = 0x70000008;
+
|-
 
+
|
u32 reset_status = *(u32 *)APBDEV_PMC_RST_STATUS_0;
+
| 0x7000FB2C
 
+
|-
// Check for regular power on
+
|  
if (reset_status == 0)
+
| 0x7000FB30
{   
+
|-
    // 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);
+
| 0x7000FB34
}
+
|-
else
+
| FUSE_OPT_GPU_TPC0_DISABLE_CP2
{
+
| 0x7000FB38
    // Restore strapping options from PMC scratch
+
|-
    *(u32 *)APB_MISC_PP_STRAPPING_OPT_A_0 = *(u32 *)APBDEV_PMC_SECURE_SCRATCH111_0;
+
| FUSE_OPT_GPU_TPC1_DISABLE
}
+
| 0x7000FB3C
 
+
|-
// Disable write access to APBDEV_PMC_SECURE_SCRATCH111_0
+
| FUSE_OPT_GPU_TPC1_DISABLE_CP1
*(u32 *)APBDEV_PMC_SEC_DISABLE8_0 |= 0x4000;
+
| 0x7000FB40
+
|-
return *(u32 *)APBDEV_PMC_SCRATCH0_0;
+
| FUSE_OPT_GPU_TPC1_DISABLE_CP2
</syntaxhighlight>
+
| 0x7000FB44
 
+
|-
==== IROM patch 5 ====
+
| FUSE_OPT_CPU_DISABLE_CP2
This patch adjusts USB configurations.
+
| 0x7000FB48
 
+
|-
<syntaxhighlight lang="c">
+
| FUSE_OPT_GPU_DISABLE_CP2
u32 USB1_UTMIP_HSRX_CFG0_0 = 0x7D000810;
+
| 0x7000FB4C
u32 USB1_UTMIP_BIAS_CFG2_0 = 0x7D000850;
+
|-
 
+
| FUSE_USB_CALIB_EXT
// Clear UTMIP_IDLE_WAIT, UTMIP_ELASTIC_LIMIT and UTMIP_PCOUNT_UPDN_DIV,
+
| 0x7000FB50
// 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));
+
| FUSE_RESERVED_FIELD
+
| 0x7000FB54
// Clear UTMIP_HSSQUELCH_LEVEL_NEW
+
|-
*(u32 *)USB1_UTMIP_BIAS_CFG2_0 &= ~(0x07);
+
| FUSE_SPARE_REALIGNMENT_REG
+
| 0x7000FB7C
return;
+
|-
</syntaxhighlight>
+
| FUSE_SPARE_BIT_0
 
+
| 0x7000FB80
==== IROM patch 6 ====
+
|-
This patch is a factory backdoor.
+
| FUSE_SPARE_BIT_1
 
+
| 0x7000FB84
It allows controlling the debug authentication configuration using a fuse.
+
|-
 
+
| FUSE_SPARE_BIT_2
<syntaxhighlight lang="c">
+
| 0x7000FB88
u32 FUSE_ODM_INFO = 0x7000FA9C;
+
|-
 
+
| FUSE_SPARE_BIT_3
u32 odm_info = *(u32 *)FUSE_ODM_INFO;
+
| 0x7000FB8C
debug_auth_override_val = ((odm_info >> 0x08) << 0x01);
+
|-
 
+
| FUSE_SPARE_BIT_4
// Override debug authentication value stored in IRAM
+
| 0x7000FB90
*(u32 *)0x400028E4 &= ~(debug_auth_override_val);
+
|-
 
+
| FUSE_SPARE_BIT_5
/*
+
| 0x7000FB94
    Untranslated instructions:
+
|-
+
| FUSE_SPARE_BIT_6
    CMP    R0, #0
+
| 0x7000FB98
*/
+
|-
+
| FUSE_SPARE_BIT_7
return;
+
| 0x7000FB9C
</syntaxhighlight>
+
|-
 
+
| FUSE_SPARE_BIT_8
==== IROM patch 7 ====
+
| 0x7000FBA0
This patch is a bugfix.
+
|-
 
+
| FUSE_SPARE_BIT_9
It prevents overflowing IRAM (0x40010000) when copying the warmboot binary from DRAM.
+
| 0x7000FBA4
 
+
|-
<syntaxhighlight lang="c">
+
| FUSE_SPARE_BIT_10
u32 APBDEV_PMC_CNTRL_0 = 0x7000E400;
+
| 0x7000FBA8
+
|-
u32 warmboot_header_addr = 0x400049F0;
+
| FUSE_SPARE_BIT_11
u32 warmboot_bin_size = *(u32 *)warmboot_bin_header_addr;
+
| 0x7000FBAC
+
|-
// Invalid warmboot binary size
+
| FUSE_SPARE_BIT_12
if (warmboot_size >> 0x11)
+
| 0x7000FBB0
{
+
|-
    // Assert MAIN_RST
+
| FUSE_SPARE_BIT_13
    // 0x40004BF0 comes from R4 and the bootrom doesn't bother to change it
+
| 0x7000FBB4
    *(u32 *)APBDEV_PMC_CNTRL_0 = 0x40004BF0;
+
|-
 
+
| FUSE_SPARE_BIT_14
    // Deadlock
+
| 0x7000FBB8
    while(1);
+
|-
}
+
| FUSE_SPARE_BIT_15
+
| 0x7000FBBC
/*
+
|-
    Untranslated instructions:
+
| FUSE_SPARE_BIT_16
+
| 0x7000FBC0
    LDR    R0, =0x40010000
+
|-
    LDR    R2, [warmboot_bin_header_addr]
+
| FUSE_SPARE_BIT_17
*/
+
| 0x7000FBC4
 +
|-
 +
| FUSE_SPARE_BIT_18
 +
| 0x7000FBC8
 +
|-
 +
| FUSE_SPARE_BIT_19
 +
| 0x7000FBCC
 +
|-
 +
| FUSE_SPARE_BIT_20
 +
| 0x7000FBD0
 +
|-
 +
| FUSE_SPARE_BIT_21
 +
| 0x7000FBD4
 +
|-
 +
| FUSE_SPARE_BIT_22
 +
| 0x7000FBD8
 +
|-
 +
| FUSE_SPARE_BIT_23
 +
| 0x7000FBDC
 +
|-
 +
| FUSE_SPARE_BIT_24
 +
| 0x7000FBE0
 +
|-
 +
| FUSE_SPARE_BIT_25
 +
| 0x7000FBE4
 +
|-
 +
| FUSE_SPARE_BIT_26
 +
| 0x7000FBE8
 +
|-
 +
| FUSE_SPARE_BIT_27
 +
| 0x7000FBEC
 +
|-
 +
| FUSE_SPARE_BIT_28
 +
| 0x7000FBF0
 +
|-
 +
| FUSE_SPARE_BIT_29
 +
| 0x7000FBF4
 +
|}
   −
  return;
+
==== FUSE_RESERVED_ODM28 ====
</syntaxhighlight>
+
{| class="wikitable" border="1"
 
+
!  Bits
==== IROM patch 8 ====
+
!  Description
This patch is a bugfix.
+
|-
 
+
| 0
It sets the correct warmboot binary entrypoint address for RSA signature verification, which would be done in DRAM instead of IRAM without this patch.
+
| RegulatorType
 
+
|}
<syntaxhighlight lang="c">
+
 
  u32 warmboot_addr_ptr = 0x40010238;
+
==== FUSE_BOOT_SECURITY_INFO ====
  u32 warmboot_entry_addr_ptr = 0x40004C28;
+
{| class="wikitable" border="1"
 
+
!  Bits
  *(u32 *)warmboot_entry_addr_ptr = *(u32 *)warmboot_addr_ptr;
+
!  Description
 
+
|-
  /*
+
| 0-1
     Untranslated instructions:
+
| Authentication (0 = AES_CMAC, 1 = PKC_RSA)
   
+
|-
     LDR    R2, [warmboot_addr_ptr]
+
| 2
  */
+
| Encryption (0 = DISABLE, 1 = ENABLE)
   
+
|-
  return;
+
| 3
</syntaxhighlight>
+
| Fuse encryption (0 = DISABLE, 1 = ENABLE)
 
+
|-
==== IROM patches 9 and 10 ====
+
| 4-6
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A.
+
| Fuse encryption select (0 = TEST_KEY, 1 = NVIDIA_KEY, 2 to 7 = OEM_KEY_1 to OEM_KEY_6)
 
+
|}
==== IROM patch 11 ====
+
 
This patch forces the value of [[Security_Engine|SE_TZRAM_SECURITY]] to be 0x01 instead of restoring it from the saved SE context.
+
Stores configuration values for the new boot security mechanism.
 
+
 
== Anti-downgrade ==
+
Mariko units have authentication set to PKC_RSA, encryption enabled, fuse encryption enabled and fuse encryption select set to OEM_KEY_1 (development) or OEM_KEY_2 (retail).
The first bootloader verifies [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]] to prevent downgrading.
+
 
How many fuses are expected to be burnt depends the device's unit type as below.
+
= Bitmap =
 
+
The actual hardware fuses are stored in a bitmap and may be programmed through the fuse driver after enabling fuse programming.
{| class="wikitable" border="1"
+
 
|-
+
Fuse numbers are relative to the start of the fuse bitmap where each element is a 4 byte word and has a redundant alias. A single fuse write operation must always write the same value to '''fuse_bitmap + ((fuse_number + 0) << 2)''' (PRIMARY_ALIAS) and '''fuse_bitmap + ((fuse_number + 1) << 2)''' (REDUNDANT_ALIAS). However, spare bits and all fuses afterwards in the fuse bitmap, no longer have a redundant alias.
! System version
+
 
! Expected number of burnt fuses (retail)
+
== Erista ==
! Expected number of burnt fuses (non-retail)
+
{| class="wikitable" border="1"
|-
+
!  Name
| 1.0.0
+
!  Number
 +
!  Redundant number
 +
!  Bits
 +
|-
 +
| enable_fuse_program
 +
| 0
 +
| 1
 +
| 0
 +
|-
 +
| disable_fuse_program
 +
| 0
 +
| 1
 +
| 1
 +
|-
 +
| bypass_fuses
 +
| 0
 +
| 1
 +
| 2
 +
|-
 +
| jtag_direct_access_disable
 +
| 0
 +
| 1
 +
| 3
 +
|-
 +
| production_mode
 +
| 0
 +
| 1
 +
| 4
 +
|-
 +
| jtag_secureid_valid
 +
| 0
 +
| 1
 +
| 5
 +
|-
 +
| odm_lock
 +
| 0
 +
| 1
 +
| 6-9
 +
|-
 +
| fa_mode
 +
| 0
 +
| 1
 +
| 10
 +
|-
 +
| security_mode
 +
| 0
 +
| 1
 +
| 11
 +
|-
 +
| arm_debug_dis
 +
| 0
 +
| 1
 +
| 12
 +
|-
 +
| obs_dis
 +
| 0
 +
| 1
 +
| 13
 +
|-
 +
| public_key0
 +
| 10
 +
| 11
 +
| 30-31
 +
|-
 +
| public_key0
 +
| 12
 +
| 13
 +
| 0-29
 +
|-
 +
| public_key1
 +
| 12
 +
| 13
 +
| 30-31
 +
|-
 +
| public_key1
 +
| 14
 +
| 15
 +
| 0-29
 +
|-
 +
| public_key2
 +
| 14
 +
| 15
 +
| 30-31
 +
|-
 +
| public_key2
 +
| 16
 +
| 17
 +
| 0-29
 +
|-
 +
| public_key3
 +
| 16
 +
| 17
 +
| 30-31
 +
|-
 +
| public_key3
 +
| 18
 +
| 19
 +
| 0-29
 +
|-
 +
| public_key4
 +
| 18
 +
| 19
 +
| 30-31
 +
|-
 +
| public_key4
 +
| 20
 +
| 21
 +
| 0-29
 +
|-
 +
| public_key5
 +
| 20
 +
| 21
 +
| 30-31
 +
|-
 +
| public_key5
 +
| 22
 +
| 23
 +
| 0-29
 +
|-
 +
| public_key6
 +
| 22
 +
| 23
 +
| 30-31
 +
|-
 +
| public_key6
 +
| 24
 +
| 25
 +
| 0-29
 +
|-
 +
| public_key7
 +
| 24
 +
| 25
 +
| 30-31
 +
|-
 +
| public_key7
 +
| 26
 +
| 27
 +
| 0-29
 +
|-
 +
| private_key0
 +
| 34
 +
| 35
 +
| 12-31
 +
|-
 +
| private_key0
 +
| 36
 +
| 37
 +
| 0-11
 +
|-
 +
| private_key1
 +
| 36
 +
| 37
 +
| 12-31
 +
|-
 +
| private_key1
 +
| 38
 +
| 39
 +
| 0-11
 +
|-
 +
| private_key2
 +
| 38
 +
| 39
 +
| 12-31
 +
|-
 +
| private_key2
 +
| 40
 +
| 41
 +
| 0-11
 +
|-
 +
| private_key3
 +
| 40
 +
| 41
 +
| 12-31
 +
|-
 +
| private_key3
 +
| 42
 +
| 43
 +
| 0-11
 +
|-
 +
| private_key4
 +
| 42
 +
| 43
 +
| 12-31
 +
|-
 +
| private_key4
 +
| 44
 +
| 45
 +
| 0-11
 +
|-
 +
| boot_device_info
 +
| 44
 +
| 45
 +
| 12-27
 +
|-
 +
| reserved_sw
 +
| 44
 +
| 45
 +
| 28-31
 +
|-
 +
| reserved_sw
 +
| 46
 +
| 47
 +
| 0-3
 +
|-
 +
| reserved_odm0
 +
| 46
 +
| 47
 +
| 5-31
 +
|-
 +
| reserved_odm0
 +
| 48
 +
| 49
 +
| 0-4
 +
|-
 +
| reserved_odm1
 +
| 48
 +
| 49
 +
| 5-31
 +
|-
 +
| reserved_odm1
 +
| 50
 +
| 51
 +
| 0-4
 +
|-
 +
| reserved_odm2
 +
| 50
 +
| 51
 +
| 5-31
 +
|-
 +
| reserved_odm2
 +
| 52
 +
| 53
 +
| 0-4
 +
|-
 +
| reserved_odm3
 +
| 52
 +
| 53
 +
| 5-31
 +
|-
 +
| reserved_odm3
 +
| 54
 +
| 55
 +
| 0-4
 +
|-
 +
| reserved_odm4
 +
| 54
 +
| 55
 +
| 5-31
 +
|-
 +
| reserved_odm4
 +
| 56
 +
| 57
 +
| 0-4
 +
|-
 +
| reserved_odm5
 +
| 56
 +
| 57
 +
| 5-31
 +
|-
 +
| reserved_odm5
 +
| 58
 +
| 59
 +
| 0-4
 +
|-
 +
| [[#reserved_odm6|reserved_odm6]]
 +
| 58
 +
| 59
 +
| 5-31
 +
|-
 +
| [[#reserved_odm6|reserved_odm6]]
 +
| 60
 +
| 61
 +
| 0-4
 +
|-
 +
| [[#reserved_odm7|reserved_odm7]]
 +
| 60
 +
| 61
 +
| 5-31
 +
|-
 +
| [[#reserved_odm7|reserved_odm7]]
 +
| 62
 +
| 63
 +
| 0-4
 +
|-
 +
| kfuse_privkey_ctrl
 +
| 64
 +
| 65
 +
| 13-14
 +
|-
 +
| package_info
 +
| 64
 +
| 65
 +
| 15-18
 +
|-
 +
| opt_vendor_code
 +
| 64
 +
| 65
 +
| 19-22
 +
|-
 +
| opt_fab_code
 +
| 64
 +
| 65
 +
| 23-28
 +
|-
 +
| opt_lot_code_0
 +
| 64
 +
| 65
 +
| 29-31
 +
|-
 +
| opt_lot_code_0
 +
| 66
 +
| 67
 +
| 0-28
 +
|-
 +
| opt_lot_code_1
 +
| 66
 +
| 67
 +
| 29-31
 +
|-
 +
| opt_lot_code_1
 +
| 68
 +
| 69
 +
| 0-24
 +
|-
 +
| opt_wafer_id
 +
| 68
 +
| 69
 +
| 25-30
 +
|-
 +
| opt_x_coordinate
 +
| 68
 +
| 69
 +
| 31
 +
|-
 +
| opt_x_coordinate
 +
| 70
 +
| 71
 +
| 0-7
 +
|-
 +
| opt_y_coordinate
 +
| 70
 +
| 71
 +
| 8-16
 +
|-
 +
| opt_sec_debug_en
 +
| 70
 +
| 71
 +
| 17
 +
|-
 +
| opt_ops_reserved
 +
| 70
 +
| 71
 +
| 18-23
 +
|-
 +
| sata_calib
 +
| 70
 +
| 71
 +
| 24-25
 +
|-
 +
| opt_priv_sec_en
 +
| 90
 +
| 91
 +
| 8
 +
|-
 +
| pkc_disable
 +
| 90
 +
| 91
 +
| 9
 +
|-
 +
| fuse2tsec_debug_disable
 +
| 90
 +
| 91
 +
| 10
 +
|-
 +
| secure_provision_index
 +
| 90
 +
| 91
 +
| 24-27
 +
|-
 +
| secure_provision_info
 +
| 90
 +
| 91
 +
| 28-29
 +
|-
 +
| spare_bit_0
 +
| 100
 +
| None
 +
| 16
 +
|-
 +
| spare_bit_1
 +
| 100
 +
| None
 +
| 17
 +
|-
 +
| spare_bit_2
 +
| 100
 +
| None
 +
| 18
 +
|-
 +
| spare_bit_3
 +
| 100
 +
| None
 +
| 19
 +
|-
 +
| spare_bit_4
 +
| 100
 +
| None
 +
| 20
 +
|-
 +
| spare_bit_5
 +
| 100
 +
| None
 +
| 21
 +
|-
 +
| spare_bit_6
 +
| 100
 +
| None
 +
| 22
 +
|-
 +
| spare_bit_7
 +
| 100
 +
| None
 +
| 23
 +
|-
 +
| spare_bit_8
 +
| 100
 +
| None
 +
| 24
 +
|-
 +
| spare_bit_9
 +
| 100
 +
| None
 +
| 25
 +
|-
 +
| spare_bit_10
 +
| 100
 +
| None
 +
| 26
 +
|-
 +
| spare_bit_11
 +
| 100
 +
| None
 +
| 27
 +
|-
 +
| spare_bit_12
 +
| 100
 +
| None
 +
| 28
 +
|-
 +
| spare_bit_13
 +
| 100
 +
| None
 +
| 29
 +
|-
 +
| spare_bit_14
 +
| 100
 +
| None
 +
| 30
 +
|-
 +
| spare_bit_15
 +
| 100
 +
| None
 +
| 31
 +
|-
 +
| spare_bit_16
 +
| 101
 +
| None
 +
| 16
 +
|-
 +
| spare_bit_17
 +
| 101
 +
| None
 +
| 17
 +
|-
 +
| spare_bit_18
 +
| 101
 +
| None
 +
| 18
 +
|-
 +
| spare_bit_19
 +
| 101
 +
| None
 +
| 19
 +
|-
 +
| spare_bit_20
 +
| 101
 +
| None
 +
| 20
 +
|-
 +
| spare_bit_21
 +
| 101
 +
| None
 +
| 21
 +
|-
 +
| spare_bit_22
 +
| 101
 +
| None
 +
| 22
 +
|-
 +
| spare_bit_23
 +
| 101
 +
| None
 +
| 23
 +
|-
 +
| spare_bit_24
 +
| 101
 +
| None
 +
| 24
 +
|-
 +
| spare_bit_25
 +
| 101
 +
| None
 +
| 25
 +
|-
 +
| spare_bit_26
 +
| 101
 +
| None
 +
| 26
 +
|-
 +
| spare_bit_27
 +
| 101
 +
| None
 +
| 27
 +
|-
 +
| spare_bit_28
 +
| 101
 +
| None
 +
| 28
 +
|-
 +
| spare_bit_29
 +
| 101
 +
| None
 +
| 29
 +
|-
 +
| spare_bit_30
 +
| 101
 +
| None
 +
| 30
 +
|-
 +
| spare_bit_31
 +
| 101
 +
| None
 +
| 31
 +
|-
 +
| aid
 +
| 103
 +
| None
 +
| 2-31
 +
|-
 +
| aid
 +
| 104
 +
| None
 +
| 0-1
 +
|-
 +
| reshift_fcpu0
 +
| 106
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu1
 +
| 107
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu2
 +
| 108
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu3
 +
| 109
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank0
 +
| 110
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank1
 +
| 111
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank2
 +
| 112
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank3
 +
| 113
 +
| None
 +
| 0-31
 +
|-
 +
| [[#irom_patch|irom_patch]]
 +
| 114
 +
| None
 +
| Variable
 +
|}
 +
 
 +
=== reserved_odm6 ===
 +
Used for [[#Anti-downgrade|anti-downgrade]] control.
 +
 
 +
=== reserved_odm7 ===
 +
Used for [[#Anti-downgrade|anti-downgrade]] control.
 +
 
 +
=== irom_patch ===
 +
Bootrom patches are burned to the hardware fuse bitmap using a specific format (see [https://gist.github.com/hexkyz/98c28e292597d8fc7bef7a2200e792d7 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 following represents the patch data dumped from a Switch console:
 +
<syntaxhighlight>
 +
RAM:00000000 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000000
 +
RAM:00000000
 +
RAM:00000000 irom_svc_dispatch
 +
RAM:00000000  STMFD  SP!, {R0-R2}                  ; ipatches (new):
 +
RAM:00000000                                        ;  0: 0x0b57df00 0x001016ae 0x0000df00 : svc #0x00 (offset 0x48)
 +
RAM:00000000                                        ;  1: 0x1820df22 0x00103040 0x0000df22 : svc #0x22 (offset 0x8c)
 +
RAM:00000000                                        ;  2: 0x3797df26 0x00106f2e 0x0000df26 : svc #0x26 (offset 0x94)
 +
RAM:00000000                                        ;  3: 0x3b4d2100 0x0010769a 0x00002100 : movs r1, #0x00
 +
RAM:00000000                                        ;  4: 0x042bdf2c 0x00100856 0x0000df2c : svc #0x2c (offset 0xa0)
 +
RAM:00000000                                        ;  5: 0x37aadf42 0x00106f54 0x0000df42 : svc #0x42 (offset 0xcc)
 +
RAM:00000000                                        ;  6: 0x0972df4b 0x001012e4 0x0000df4b : svc #0x4b (offset 0xde)
 +
RAM:00000000                                        ;  7: 0x2293df54 0x00104526 0x0000df54 : svc #0x54 (offset 0xf0)
 +
RAM:00000000                                        ;  8: 0x21fadf5d 0x001043f4 0x0000df5d : svc #0x5d (offset 0x102)
 +
RAM:00000000                                        ;  9: 0xbba2ac57 0x00117744 0x0000ac57 : data
 +
RAM:00000000                                        ; 10: 0xbbac3d19 0x00117758 0x00003d19 : data
 +
RAM:00000000                                        ; 11: 0x1e952001 0x00103d2a 0x00002001 : movs r0, #0x01
 +
RAM:00000000                                        ;
 +
RAM:00000000                                        ; ipatches (old):
 +
RAM:00000000                                        ;  0: 0x0b57df00 0x001016ae 0x0000df00 : svc #0x00 (offset 0x48)
 +
RAM:00000000                                        ;  1: 0x1820df22 0x00103040 0x0000df22 : svc #0x22 (offset 0x8c)
 +
RAM:00000000                                        ;  2: 0x3797df26 0x00106f2e 0x0000df26 : svc #0x26 (offset 0x94)
 +
RAM:00000000                                        ;  3: 0x7d9e2000 0x0010fb3c 0x00002000 : movs r0, #0x00
 +
RAM:00000000                                        ;  4: 0x042bdf2c 0x00100856 0x0000df2c : svc #0x2c (offset 0xa0)
 +
RAM:00000000                                        ;  5: 0x37aadf42 0x00106f54 0x0000df42 : svc #0x42 (offset 0xcc)
 +
RAM:00000000                                        ;  6: 0x0972df4b 0x001012e4 0x0000df4b : svc #0x4b (offset 0xde)
 +
RAM:00000000                                        ;  7: 0x2293df54 0x00104526 0x0000df54 : svc #0x54 (offset 0xf0)
 +
RAM:00000000                                        ;  8: 0x21fadf5d 0x001043f4 0x0000df5d : svc #0x5d (offset 0x102)
 +
RAM:00000000                                        ;  9: 0xbba2ac57 0x00117744 0x0000ac57 : data
 +
RAM:00000000                                        ; 10: 0xbbac3d19 0x00117758 0x00003d19 : data
 +
RAM:00000000                                        ; 11: 0x1e952001 0x00103d2a 0x00002001 : movs r0, #0x01
 +
RAM:00000004  MOV    R2, LR
 +
RAM:00000008  SUB    R2, R2, #2
 +
RAM:0000000C  LDR    R2, [R2]
 +
RAM:00000010  AND    R2, R2, #0xFF
 +
RAM:00000014  MOV    R2, R2,LSL#1
 +
RAM:00000018  LDR    R0, =0x1007B0
 +
RAM:0000001C  LDR    R1, =0x1007F8
 +
RAM:00000020  SUB    R1, R1, R0
 +
RAM:00000024  LDR    R0, =0x40004C30
 +
RAM:00000028  ADD    R0, R0, R1
 +
RAM:0000002C  ADD    R2, R2, R0
 +
RAM:00000030  ORR    R2, R2, #1
 +
RAM:00000034  LDMFD  SP!, {R0,R1}
 +
RAM:00000038  BX      R2
 +
RAM:00000038 ; End of function irom_svc_dispatch
 +
RAM:00000038
 +
RAM:00000038 ; ---------------------------------------------------------------------------
 +
RAM:0000003C dword_3C DCD 0x1007B0                  ; DATA XREF: irom_svc_dispatch+18↑r
 +
RAM:00000040 dword_40 DCD 0x1007F8                  ; DATA XREF: irom_svc_dispatch+1C↑r
 +
RAM:00000044 dword_44 DCD 0x40004C30                ; DATA XREF: irom_svc_dispatch+24↑r
 +
RAM:00000048  CODE16
 +
RAM:00000048
 +
RAM:00000048 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000048
 +
RAM:00000048
 +
RAM:00000048 sub_48
 +
RAM:00000048  MOVS    R2, #0                        ; 0: 0x0b57df00 0x001016ae 0x0000df00 : svc #0x00 (offset 0x48)
 +
RAM:0000004A  MVNS    R2, R2
 +
RAM:0000004C  LDR    R1, =0x60006410
 +
RAM:0000004E  STR    R2, [R1,#0x30]
 +
RAM:00000050  STR    R2, [R1,#0x38]
 +
RAM:00000052  LDR    R1, =0x600060F8
 +
RAM:00000054  STR    R2, [R1]
 +
RAM:00000056  STR    R2, [R1,#4]
 +
RAM:00000058  LDR    R1, =0x60006284
 +
RAM:0000005A  STR    R2, [R1]
 +
RAM:0000005C  STR    R2, [R1,#0x18]
 +
RAM:0000005E  ADDS    R1, #0x80
 +
RAM:00000060  ADDS    R1, #0x1C
 +
RAM:00000062  STR    R2, [R1]
 +
RAM:00000064  STR    R2, [R1,#8]
 +
RAM:00000066  STR    R2, [R1,#0x10]
 +
RAM:00000068  ADDS    R1, #0x80
 +
RAM:0000006A  STR    R2, [R1]
 +
RAM:0000006C  STR    R2, [R1,#4]
 +
RAM:0000006E  LDR    R1, =0x60006554
 +
RAM:00000070  STR    R2, [R1]
 +
RAM:00000072  MOVS    R2, #0xA0000000
 +
RAM:00000076  LDR    R1, =0x60006148
 +
RAM:00000078  STR    R2, [R1]
 +
RAM:0000007A  ADDS    R1, #0x38 ; '8'
 +
RAM:0000007C  STR    R2, [R1]
 +
RAM:0000007E  MOVS    R2, #0xE0000000
 +
RAM:00000082  LDR    R1, =0x600066A0
 +
RAM:00000084  STR    R2, [R1]
 +
RAM:00000086  MOVS    R1, #0
 +
RAM:00000088  MOVS    R0, #0xE
 +
RAM:0000008A  B      pop_r2_mov_pc_lr
 +
RAM:0000008A ; End of function sub_48
 +
RAM:0000008A
 +
RAM:0000008C
 +
RAM:0000008C ; =============== S U B R O U T I N E =======================================
 +
RAM:0000008C
 +
RAM:0000008C
 +
RAM:0000008C sub_8C
 +
RAM:0000008C  LDR    R0, [R1,#0x18]                ; 1: 0x1820df22 0x00103040 0x0000df22 : svc #0x22 (offset 0x8c)
 +
RAM:0000008E  MOVS    R2, #1
 +
RAM:00000090  ORRS    R0, R2
 +
RAM:00000092  B      pop_r2_mov_pc_lr
 +
RAM:00000092 ; End of function sub_8C
 +
RAM:00000092
 +
RAM:00000094
 +
RAM:00000094 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000094
 +
RAM:00000094
 +
RAM:00000094 sub_94
 +
RAM:00000094  LDR    R2, [R4,#0x50]                ; 2: 0x3797df26 0x00106f2e 0x0000df26 : svc #0x26 (offset 0x94)
 +
RAM:00000096  ADDS    R2, R2, #2
 +
RAM:00000098  STR    R2, [R4,#0x50]
 +
RAM:0000009A  SUBS    R1, #0x80
 +
RAM:0000009C  STR    R1, [R4,#0x34]
 +
RAM:0000009E  B      pop_r2_mov_pc_lr
 +
RAM:0000009E ; End of function sub_94
 +
RAM:0000009E
 +
RAM:000000A0
 +
RAM:000000A0 ; =============== S U B R O U T I N E =======================================
 +
RAM:000000A0
 +
RAM:000000A0
 +
RAM:000000A0 sub_A0
 +
RAM:000000A0
 +
RAM:000000A0 ; FUNCTION CHUNK AT RAM:00000148 SIZE 00000004 BYTES
 +
RAM:000000A0
 +
RAM:000000A0  MOVS    R0, #0x70000000              ; 4: 0x042bdf2c 0x00100856 0x0000df2c : svc #0x2c (offset 0xa0)
 +
RAM:000000A4  LDR    R6, =dword_7000EF14
 +
RAM:000000A6  LDR    R2, =dword_7000E5B4
 +
RAM:000000A8  LDR    R2, [R2]
 +
RAM:000000AA  CMP    R2, #0
 +
RAM:000000AC  BEQ    loc_B4
 +
RAM:000000AE  LDR    R2, [R6]
 +
RAM:000000B0  STR    R2, [R0,#8]
 +
RAM:000000B2  B      loc_BC
 +
RAM:000000B4 ; ---------------------------------------------------------------------------
 +
RAM:000000B4
 +
RAM:000000B4 loc_B4                                  ; CODE XREF: sub_A0+C↑j
 +
RAM:000000B4  LDR    R2, [R0,#8]
 +
RAM:000000B6  LSRS    R0, R0, #0x12
 +
RAM:000000B8  ORRS    R2, R0
 +
RAM:000000BA  STR    R2, [R6]
 +
RAM:000000BC
 +
RAM:000000BC loc_BC                                  ; CODE XREF: sub_A0+12↑j
 +
RAM:000000BC  LDR    R6, =dword_7000E9C0
 +
RAM:000000BE  LDR    R0, [R6]
 +
RAM:000000C0  MOVS    R2, #0x4000
 +
RAM:000000C4  ORRS    R2, R0
 +
RAM:000000C6  STR    R2, [R6]
 +
RAM:000000C8  LDR    R0, [R5,#0x10]
 +
RAM:000000CA  B      pop_r2_mov_pc_lr
 +
RAM:000000CA ; End of function sub_A0
 +
RAM:000000CA
 +
RAM:000000CC
 +
RAM:000000CC ; =============== S U B R O U T I N E =======================================
 +
RAM:000000CC
 +
RAM:000000CC
 +
RAM:000000CC sub_CC
 +
RAM:000000CC  MOVS    R2, #0xF000000                ; 5: 0x37aadf42 0x00106f54 0x0000df42 : svc #0x42 (offset 0xcc)
 +
RAM:000000D0  BICS    R1, R2
 +
RAM:000000D2  STR    R1, [R4,#0x10]
 +
RAM:000000D4  LDR    R1, [R4,#0x50]
 +
RAM:000000D6  MOVS    R2, #7
 +
RAM:000000D8  BICS    R1, R2
 +
RAM:000000DA  STR    R1, [R4,#0x50]
 +
RAM:000000DC  B      pop_r2_mov_pc_lr
 +
RAM:000000DC ; End of function sub_CC
 +
RAM:000000DC
 +
RAM:000000DE
 +
RAM:000000DE ; =============== S U B R O U T I N E =======================================
 +
RAM:000000DE
 +
RAM:000000DE
 +
RAM:000000DE sub_DE
 +
RAM:000000DE  LDR    R2, =dword_7000FA9C          ; 6: 0x0972df4b 0x001012e4 0x0000df4b : svc #0x4b (offset 0xde)
 +
RAM:000000E0  LDR    R2, [R2]
 +
RAM:000000E2  LSRS    R2, R2, #8
 +
RAM:000000E4  LSLS    R2, R2, #1
 +
RAM:000000E6  LDR    R1, [R4]
 +
RAM:000000E8  BICS    R1, R2
 +
RAM:000000EA  STR    R1, [R4]
 +
RAM:000000EC  CMP    R0, #0
 +
RAM:000000EE  B      pop_r2_mov_pc_lr
 +
RAM:000000EE ; End of function sub_DE
 +
RAM:000000EE
 +
RAM:000000F0
 +
RAM:000000F0 ; =============== S U B R O U T I N E =======================================
 +
RAM:000000F0
 +
RAM:000000F0
 +
RAM:000000F0 sub_F0
 +
RAM:000000F0
 +
RAM:000000F0 arg_0=  0
 +
RAM:000000F0
 +
RAM:000000F0  LDR    R0, =0x400049F0              ; 7: 0x2293df54 0x00104526 0x0000df54 : svc #0x54 (offset 0xf0)
 +
RAM:000000F2  LDR    R2, [R0]
 +
RAM:000000F4  STR    R2, [SP,#arg_0]
 +
RAM:000000F6  LDR    R0, =0x40010000
 +
RAM:000000F8  LSRS    R2, R2, #17
 +
RAM:000000FA  BEQ    pop_r2_mov_pc_lr              ; if ([0x400049F0] >> 17) == 0) {
 +
RAM:000000FA                                        ;  r2 = [0x400049F0];
 +
RAM:000000FA                                        ; } else {
 +
RAM:000000FC  LDR    R0, =APBDEV_PMC_CNTRL_0
 +
RAM:000000FE  STR    R4, [R0]                      ;  write APBDEV_PMC_CNTRL
 +
RAM:00000100
 +
RAM:00000100 loc_100                                ; CODE XREF: sub_F0:loc_100↓j
 +
RAM:00000100  B      loc_100                      ;  hang
 +
RAM:00000100 ; End of function sub_F0                ; }
 +
RAM:00000100
 +
RAM:00000102
 +
RAM:00000102 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000102
 +
RAM:00000102
 +
RAM:00000102 sub_102
 +
RAM:00000102
 +
RAM:00000102 arg_0=  0
 +
RAM:00000102
 +
RAM:00000102  LDR    R2, =0x40010220              ; 8: 0x21fadf5d 0x001043f4 0x0000df5d : svc #0x5d (offset 0x102)
 +
RAM:00000104  STR    R2, [SP,#arg_0]              ; set r2 retval = [0x40010220]
 +
RAM:00000106  LDR    R2, [R2,#0x18]
 +
RAM:00000108  ADDS    R0, #0xFC
 +
RAM:0000010A  STR    R2, [R0,#0x1C]                ; [r0+0x118] = [0x40010220 + 0x18]
 +
RAM:0000010C  B      pop_r2_mov_pc_lr
 +
RAM:0000010C ; End of function sub_102
 +
RAM:0000010C
 +
RAM:0000010C ; ---------------------------------------------------------------------------
 +
RAM:0000010E  DCB    0
 +
RAM:0000010F  DCB    0
 +
RAM:00000110 off_110 DCD 0x60006410                  ; DATA XREF: sub_48+4↑r
 +
RAM:00000114 off_114 DCD 0x600060F8                  ; DATA XREF: sub_48+A↑r
 +
RAM:00000118 off_118 DCD 0x60006284                  ; DATA XREF: sub_48+10↑r
 +
RAM:0000011C off_11C DCD 0x60006554                  ; DATA XREF: sub_48+26↑r
 +
RAM:00000120 off_120 DCD 0x60006148                  ; DATA XREF: sub_48+2E↑r
 +
RAM:00000124 off_124 DCD 0x600066A0                  ; DATA XREF: sub_48+3A↑r
 +
RAM:00000128 off_128 DCD dword_7000EF14              ; DATA XREF: sub_A0+4↑r
 +
RAM:0000012C off_12C DCD dword_7000E5B4              ; DATA XREF: sub_A0+6↑r
 +
RAM:00000130 off_130 DCD dword_7000E9C0              ; DATA XREF: sub_A0:loc_BC↑r
 +
RAM:00000134 off_134 DCD dword_7000FA9C              ; DATA XREF: sub_DE↑r
 +
RAM:00000138 off_138 DCD 0x400049F0                  ; DATA XREF: sub_F0↑r
 +
RAM:0000013C dword_13C DCD 0x40010000                ; DATA XREF: sub_F0+6↑r
 +
RAM:00000140 off_140 DCD APBDEV_PMC_CNTRL_0          ; DATA XREF: sub_F0+C↑r
 +
RAM:00000144 off_144 DCD 0x40010220                  ; DATA XREF: sub_102↑r
 +
RAM:00000148 ; ---------------------------------------------------------------------------
 +
RAM:00000148 ; START OF FUNCTION CHUNK FOR sub_A0
 +
RAM:00000148
 +
RAM:00000148 pop_r2_mov_pc_lr                        ; CODE XREF: sub_48+42↑j
 +
RAM:00000148                                        ; sub_8C+6↑j ...
 +
RAM:00000148  POP    {R2}
 +
RAM:0000014A  MOV    PC, LR
 +
RAM:0000014A ; END OF FUNCTION CHUNK FOR sub_A0
 +
</syntaxhighlight>
 +
 
 +
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices.
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 3 ====
 +
This patch ensures that waiting on PRC_PENDING from the XUSB_DEV register T_XUSB_DEV_XHCI_PORTSC never fails.
 +
 
 +
In the second batch of patched units ([[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]] set to revision 7.0) this patch has been replaced with a fix for [[Switch_System_Flaws#Hardware|CVE-2018-6242]] (arbitrary copy when handling USB control requests in RCM). By setting R1 to 0 at address 0x0010769A in the bootrom, the upper 16 bits of the USB control request's wLength field are cleared out, effectively limiting the request's size to a maximum of 255 bytes.
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 6 ====
 +
This patch is a factory backdoor.
 +
 
 +
It allows controlling the debug authentication configuration using a fuse.
 +
 
 +
<syntaxhighlight lang="c">
 +
u32 FUSE_ODM_INFO = 0x7000FA9C;
 +
 
 +
u32 odm_info = *(u32 *)FUSE_ODM_INFO;
 +
debug_auth_override_val = ((odm_info >> 0x08) << 0x01);
 +
 
 +
// Override debug authentication value stored in IRAM
 +
*(u32 *)0x400028E4 &= ~(debug_auth_override_val);
 +
 
 +
/*
 +
    Untranslated instructions:
 +
 +
    CMP    R0, #0
 +
*/
 +
 +
return;
 +
</syntaxhighlight>
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patch 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>
 +
 
 +
==== IROM patches 9 and 10 ====
 +
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A.
 +
 
 +
==== IROM patch 11 ====
 +
This patch forces the value of [[Security_Engine|SE_TZRAM_SECURITY]] to be 0x01 instead of restoring it from the saved SE context.
 +
 
 +
== Mariko ==
 +
{| class="wikitable" border="1"
 +
!  Name
 +
!  Number
 +
!  Redundant number
 +
!  Bits
 +
|-
 +
| enable_fuse_program
 +
| 0
 +
| 1
 +
| 0
 +
|-
 +
| disable_fuse_program
 +
| 0
 +
| 1
 +
| 1
 +
|-
 +
| bypass_fuses
 +
| 0
 +
| 1
 +
| 2
 +
|-
 +
| jtag_direct_access_disable
 +
| 0
 +
| 1
 +
| 3
 +
|-
 +
| production_mode
 +
| 0
 +
| 1
 +
| 4
 +
|-
 +
| jtag_secureid_valid
 +
| 0
 +
| 1
 +
| 5
 +
|-
 +
| odm_lock
 +
| 0
 +
| 1
 +
| 6-21
 +
|-
 +
| fa_mode
 +
| 0
 +
| 1
 +
| 22
 +
|-
 +
| security_mode
 +
| 0
 +
| 1
 +
| 23
 +
|-
 +
| arm_debug_dis
 +
| 0
 +
| 1
 +
| 24
 +
|-
 +
| obs_dis
 +
| 0
 +
| 1
 +
| 25
 +
|-
 +
| public_key0
 +
| 64
 +
| 65
 +
| 15-31
 +
|-
 +
| public_key0
 +
| 66
 +
| 67
 +
| 0-14
 +
|-
 +
| public_key1
 +
| 66
 +
| 67
 +
| 15-31
 +
|-
 +
| public_key1
 +
| 68
 +
| 69
 +
| 0-14
 +
|-
 +
| public_key2
 +
| 68
 +
| 69
 +
| 15-31
 +
|-
 +
| public_key2
 +
| 70
 +
| 71
 +
| 0-14
 +
|-
 +
| public_key3
 +
| 70
 +
| 71
 +
| 15-31
 +
|-
 +
| public_key3
 +
| 72
 +
| 73
 +
| 0-14
 +
|-
 +
| public_key4
 +
| 72
 +
| 73
 +
| 15-31
 +
|-
 +
| public_key4
 +
| 74
 +
| 75
 +
| 0-14
 +
|-
 +
| public_key5
 +
| 74
 +
| 75
 +
| 15-31
 +
|-
 +
| public_key5
 +
| 76
 +
| 77
 +
| 0-14
 +
|-
 +
| public_key6
 +
| 76
 +
| 77
 +
| 15-31
 +
|-
 +
| public_key6
 +
| 78
 +
| 79
 +
| 0-14
 +
|-
 +
| public_key7
 +
| 78
 +
| 79
 +
| 15-31
 +
|-
 +
| public_key7
 +
| 80
 +
| 81
 +
| 0-14
 +
|-
 +
| private_key0
 +
| 86
 +
| 87
 +
| 30-31
 +
|-
 +
| private_key0
 +
| 88
 +
| 89
 +
| 0-29
 +
|-
 +
| private_key1
 +
| 88
 +
| 89
 +
| 30-31
 +
|-
 +
| private_key1
 +
| 90
 +
| 91
 +
| 0-29
 +
|-
 +
| private_key2
 +
| 90
 +
| 91
 +
| 30-31
 +
|-
 +
| private_key2
 +
| 92
 +
| 93
 +
| 0-29
 +
|-
 +
| private_key3
 +
| 92
 +
| 93
 +
| 30-31
 +
|-
 +
| private_key3
 +
| 94
 +
| 95
 +
| 0-29
 +
|-
 +
| private_key4
 +
| 94
 +
| 95
 +
| 30-31
 +
|-
 +
| private_key4
 +
| 96
 +
| 97
 +
| 0-29
 +
|-
 +
| boot_device_info
 +
| 96
 +
| 97
 +
| 30-31
 +
|-
 +
| boot_device_info
 +
| 98
 +
| 99
 +
| 0-13
 +
|-
 +
| reserved_sw
 +
| 98
 +
| 99
 +
| 14-25
 +
|-
 +
| secure_provision_index
 +
| 152
 +
| 153
 +
| 23-26
 +
|-
 +
| secure_provision_info
 +
| 152
 +
| 153
 +
| 27-28
 +
|-
 +
| aid
 +
| 165
 +
| None
 +
| 2-31
 +
|-
 +
| aid
 +
| 166
 +
| None
 +
| 0-1
 +
|-
 +
| spare_bit_0
 +
| 167
 +
| None
 +
| 2
 +
|-
 +
| spare_bit_1
 +
| 167
 +
| None
 +
| 3
 +
|-
 +
| spare_bit_2
 +
| 167
 +
| None
 +
| 4
 +
|-
 +
| spare_bit_3
 +
| 167
 +
| None
 +
| 5
 +
|-
 +
| spare_bit_4
 +
| 167
 +
| None
 +
| 6
 +
|-
 +
| spare_bit_5
 +
| 167
 +
| None
 +
| 7
 +
|-
 +
| spare_bit_6
 +
| 167
 +
| None
 +
| 8
 +
|-
 +
| spare_bit_7
 +
| 167
 +
| None
 +
| 9
 +
|-
 +
| spare_bit_8
 +
| 167
 +
| None
 +
| 10
 +
|-
 +
| spare_bit_9
 +
| 167
 +
| None
 +
| 11
 +
|-
 +
| spare_bit_10
 +
| 167
 +
| None
 +
| 12
 +
|-
 +
| spare_bit_11
 +
| 167
 +
| None
 +
| 13
 +
|-
 +
| spare_bit_12
 +
| 167
 +
| None
 +
| 14
 +
|-
 +
| spare_bit_13
 +
| 167
 +
| None
 +
| 15
 +
|-
 +
| spare_bit_14
 +
| 167
 +
| None
 +
| 16
 +
|-
 +
| spare_bit_15
 +
| 167
 +
| None
 +
| 17
 +
|-
 +
| spare_bit_16
 +
| 167
 +
| None
 +
| 18
 +
|-
 +
| spare_bit_17
 +
| 167
 +
| None
 +
| 19
 +
|-
 +
| spare_bit_18
 +
| 167
 +
| None
 +
| 20
 +
|-
 +
| spare_bit_19
 +
| 167
 +
| None
 +
| 21
 +
|-
 +
| spare_bit_20
 +
| 167
 +
| None
 +
| 22
 +
|-
 +
| spare_bit_21
 +
| 167
 +
| None
 +
| 23
 +
|-
 +
| spare_bit_22
 +
| 167
 +
| None
 +
| 24
 +
|-
 +
| spare_bit_23
 +
| 167
 +
| None
 +
| 25
 +
|-
 +
| spare_bit_24
 +
| 167
 +
| None
 +
| 26
 +
|-
 +
| spare_bit_25
 +
| 167
 +
| None
 +
| 27
 +
|-
 +
| spare_bit_26
 +
| 167
 +
| None
 +
| 28
 +
|-
 +
| spare_bit_27
 +
| 167
 +
| None
 +
| 29
 +
|-
 +
| spare_bit_28
 +
| 167
 +
| None
 +
| 30
 +
|-
 +
| spare_bit_29
 +
| 167
 +
| None
 +
| 31
 +
|-
 +
| reshift_fcpu0
 +
| 168
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu1
 +
| 169
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu2
 +
| 170
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fcpu3
 +
| 171
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank0
 +
| 172
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank1
 +
| 173
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank2
 +
| 174
 +
| None
 +
| 0-31
 +
|-
 +
| reshift_fl2_tbank3
 +
| 175
 +
| None
 +
| 0-31
 +
|-
 +
| [[#irom_patch_2|irom_patch]]
 +
| 176
 +
| None
 +
| Variable
 +
|}
 +
 
 +
=== irom_patch ===
 +
<syntaxhighlight>
 +
RAM:00000000 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000000
 +
RAM:00000000
 +
RAM:00000000 irom_svc_dispatch
 +
RAM:00000000  STMFD  SP!, {R0-R2}                  ; ipatches:
 +
RAM:00000000                                        ;  0: 0x085bdf00 0x001010b6 0x0000df00 : svc #0x00 (offset 0x48)
 +
RAM:00000000                                        ;
 +
RAM:00000000                                        ;  0: 0x12d3df06 0x001025a6 0x0000df06 : svc #0x06 (offset 0x54)
 +
RAM:00000000                                        ;  1: 0x28144770 0x00105028 0x00004770 : bx lr
 +
RAM:00000000                                        ;  2: 0x0fb72001 0x00101f6e 0x00002001 : movs r0, #0x01
 +
RAM:00000000                                        ;  3: 0x692ddf15 0x0010d25a 0x0000df15 : svc #0x15 (offset 0x72)
 +
RAM:00000000                                        ;  4: 0x436ddf1f 0x001086da 0x0000df1f : svc #0x1f (offset 0x86)
 +
RAM:00000000                                        ;  5: 0x4376df23 0x001086ec 0x0000df23 : svc #0x23 (offset 0x8e)
 +
RAM:00000000                                        ;  6: 0x4103df2b 0x00108206 0x0000df2b : svc #0x2b (offset 0x9e)
 +
RAM:00000000                                        ;  7: 0x495c0060 0x001092b8 0x00000060 : lsls r0, r4, #1
 +
RAM:00000000                                        ;  8: 0x62e3ef5b 0x0010c5c6 0x0000ef5b
 +
RAM:00000000                                        ;  9: 0x10d1df6a 0x001021a2 0x0000df6a : svc #0x6a (offset 0x11c)
 +
RAM:00000004  MOV    R2, LR
 +
RAM:00000008  SUB    R2, R2, #2
 +
RAM:0000000C  LDR    R2, [R2]
 +
RAM:00000010  AND    R2, R2, #0xFF
 +
RAM:00000014  MOV    R2, R2,LSL#1
 +
RAM:00000018  LDR    R0, =0x10022C
 +
RAM:0000001C  LDR    R1, =0x100174
 +
RAM:00000020  SUB    R1, R1, R0
 +
RAM:00000024  LDR    R0, =0x40004164
 +
RAM:00000028  ADD    R0, R0, R1
 +
RAM:0000002C  ADD    R2, R2, R0
 +
RAM:00000030  ORR    R2, R2, #1
 +
RAM:00000034  LDMFD  SP!, {R0,R1}
 +
RAM:00000038  BX      R2
 +
RAM:00000038 ; End of function irom_svc_dispatch
 +
RAM:00000038
 +
RAM:00000038 ; ---------------------------------------------------------------------------
 +
RAM:0000003C dword_3C        DCD 0x10022C            ; DATA XREF: irom_svc_dispatch+18↑r
 +
RAM:00000040 dword_40        DCD 0x100174            ; DATA XREF: irom_svc_dispatch+1C↑r
 +
RAM:00000044 dword_44        DCD 0x40004164          ; DATA XREF: irom_svc_dispatch+24↑r
 +
RAM:00000048  CODE16
 +
RAM:00000048
 +
RAM:00000048 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000048
 +
RAM:00000048
 +
RAM:00000048 sub_48                                  ; 0: 0x085bdf00 0x001010b6 0x0000df00 : svc #0x00 (offset 0x48)
 +
RAM:00000048  CMP    R5, #0xAF
 +
RAM:0000004A  BNE    loc_4E
 +
RAM:0000004C  MOVS    R5, #0xFF
 +
RAM:0000004E
 +
RAM:0000004E loc_4E                                  ; CODE XREF: sub_48+2↑j
 +
RAM:0000004E  SUBS    R6, R5, #1
 +
RAM:00000050
 +
RAM:00000050 loc_50                                  ; CODE XREF: sub_54+18↓j
 +
RAM:00000050                                        ; sub_72+12↓j ...
 +
RAM:00000050  POP    {R2}
 +
RAM:00000052  MOV    PC, LR
 +
RAM:00000052 ; End of function sub_48
 +
RAM:00000052
 +
RAM:00000054
 +
RAM:00000054 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000054
 +
RAM:00000054
 +
RAM:00000054 sub_54                                  ; 0: 0x12d3df06 0x001025a6 0x0000df06 : svc #0x06 (offset 0x54)
 +
RAM:00000054  MOVS    R3, #7
 +
RAM:00000056
 +
RAM:00000056 loc_56                                  ; CODE XREF: sub_72+10↓j
 +
RAM:00000056                                        ; sub_8E+E↓j
 +
RAM:00000056  PUSH    {R0,R1,R3-R6}
 +
RAM:00000058  LDR    R0, =0x4000FC20
 +
RAM:0000005A  LDR    R1, =0x40040000
 +
RAM:0000005C  LDR    R3, =0xEAFFFFFE
 +
RAM:0000005E  MOVS    R4, R3
 +
RAM:00000060  MOVS    R5, R3
 +
RAM:00000062  ADDS    R6, R3, #0
 +
RAM:00000064
 +
RAM:00000064 loc_64                                  ; CODE XREF: sub_54+14↓j
 +
RAM:00000064  STMIA  R0!, {R3-R6}
 +
RAM:00000066  CMP    R0, R1
 +
RAM:00000068  BCC    loc_64
 +
RAM:0000006A  POP    {R0,R1,R3-R6}
 +
RAM:0000006C  B      loc_50
 +
RAM:0000006C ; End of function sub_54
 +
RAM:0000006C
 +
RAM:0000006E ; ---------------------------------------------------------------------------
 +
RAM:0000006E ; START OF FUNCTION CHUNK FOR sub_8E
 +
RAM:0000006E
 +
RAM:0000006E loc_6E                                  ; CODE XREF: sub_8E+8↓j
 +
RAM:0000006E  LDR    R0, =0x1002A0
 +
RAM:00000070  BX      R0
 +
RAM:00000070 ; END OF FUNCTION CHUNK FOR sub_8E
 +
RAM:00000072
 +
RAM:00000072 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000072
 +
RAM:00000072
 +
RAM:00000072 sub_72                                  ; 3: 0x692ddf15 0x0010d25a 0x0000df15 : svc #0x15 (offset 0x72)
 +
RAM:00000072  MOVS    R2, #2
 +
RAM:00000074  CMP    R0, #0x26 ; '&'
 +
RAM:00000076  BLS    loc_7A
 +
RAM:00000078  ADDS    R2, #0x50 ; 'P'
 +
RAM:0000007A
 +
RAM:0000007A loc_7A                                  ; CODE XREF: sub_72+4↑j
 +
RAM:0000007A  MOV    R3, LR
 +
RAM:0000007C  ADDS    R3, R3, R2
 +
RAM:0000007E  MOV    LR, R3
 +
RAM:00000080  CMP    R0, #0
 +
RAM:00000082  BNE    loc_56
 +
RAM:00000084  B      loc_50
 +
RAM:00000084 ; End of function sub_72
 +
RAM:00000084
 +
RAM:00000086
 +
RAM:00000086 ; =============== S U B R O U T I N E =======================================
 +
RAM:00000086
 +
RAM:00000086
 +
RAM:00000086 sub_86                                  ; 4: 0x436ddf1f 0x001086da 0x0000df1f : svc #0x1f (offset 0x86)
 +
RAM:00000086
 +
RAM:00000086 arg_8  =  8
 +
RAM:00000086
 +
RAM:00000086  MOVS    R3, R0
 +
RAM:00000088  LDR    R2, =0x5A55F0E1
 +
RAM:0000008A  STR    R2, [SP,#arg_8]
 +
RAM:0000008C  B      loc_50
 +
RAM:0000008C ; End of function sub_86
 +
RAM:0000008C
 +
RAM:0000008E
 +
RAM:0000008E ; =============== S U B R O U T I N E =======================================
 +
RAM:0000008E
 +
RAM:0000008E
 +
RAM:0000008E sub_8E                                  ; 5: 0x4376df23 0x001086ec 0x0000df23 : svc #0x23 (offset 0x8e)
 +
RAM:0000008E
 +
RAM:0000008E arg_8  =  8
 +
RAM:0000008E
 +
RAM:0000008E ; FUNCTION CHUNK AT RAM:0000006E SIZE 00000004 BYTES
 +
RAM:0000008E
 +
RAM:0000008E  MOVS    R3, R0
 +
RAM:00000090  LDR    R2, =0x5A55F0E1
 +
RAM:00000092  LDR    R0, [SP,#arg_8]
 +
RAM:00000094  CMP    R0, R2
 +
RAM:00000096  BEQ    loc_6E
 +
RAM:00000098  CMP    R0, #0
 +
RAM:0000009A  BEQ    loc_50
 +
RAM:0000009C  B      loc_56
 +
RAM:0000009C ; End of function sub_8E
 +
RAM:0000009C
 +
RAM:0000009E
 +
RAM:0000009E ; =============== S U B R O U T I N E =======================================
 +
RAM:0000009E
 +
RAM:0000009E
 +
RAM:0000009E sub_9E                                  ; 6: 0x4103df2b 0x00108206 0x0000df2b : svc #0x2b (offset 0x9e)
 +
RAM:0000009E  LDR    R0, =0x7000F900
 +
RAM:000000A0  SUBS    R0, #0xD8
 +
RAM:000000A2  MOVS    R2, #1
 +
RAM:000000A4  STR    R2, [R0]
 +
RAM:000000A6  LDR    R0, =0x7001231C
 +
RAM:000000A8  LDR    R3, =0x7041231C
 +
RAM:000000AA  MOVS    R1, #0xE0
 +
RAM:000000AC  B      loc_B4
 +
RAM:000000AE ; ---------------------------------------------------------------------------
 +
RAM:000000AE
 +
RAM:000000AE loc_AE                                  ; CODE XREF: sub_9E+2E↓j
 +
RAM:000000AE  MOVS    R1, #0xF0
 +
RAM:000000B0  B      loc_B4
 +
RAM:000000B2 ; ---------------------------------------------------------------------------
 +
RAM:000000B2
 +
RAM:000000B2 loc_B2                                  ; CODE XREF: sub_9E+32↓j
 +
RAM:000000B2  MOVS    R1, #0xC0
 +
RAM:000000B4
 +
RAM:000000B4 loc_B4                                  ; CODE XREF: sub_9E+E↑j
 +
RAM:000000B4                                        ; sub_9E+12↑j
 +
RAM:000000B4  MOVS    R4, #0
 +
RAM:000000B6
 +
RAM:000000B6 loc_B6                                  ; CODE XREF: sub_9E+28↓j
 +
RAM:000000B6  MOVS    R2, #0
 +
RAM:000000B8  STR    R1, [R0]
 +
RAM:000000BA  STR    R2, [R0,#4]
 +
RAM:000000BC  STR    R1, [R3]
 +
RAM:000000BE  STR    R2, [R3,#4]
 +
RAM:000000C0  ADDS    R1, #1
 +
RAM:000000C2  ADDS    R4, #1
 +
RAM:000000C4  CMP    R4, #7
 +
RAM:000000C6  BLS    loc_B6
 +
RAM:000000C8  LSRS    R1, R1, #4
 +
RAM:000000CA  CMP    R1, #0xE
 +
RAM:000000CC  BEQ    loc_AE
 +
RAM:000000CE  CMP    R1, #0xF
 +
RAM:000000D0  BEQ    loc_B2
 +
RAM:000000D2  MOV    R5, LR
 +
RAM:000000D4  MOVS    R0, #0
 +
RAM:000000D6
 +
RAM:000000D6 loc_D6                                  ; CODE XREF: sub_9E+56↓j
 +
RAM:000000D6  MOVS    R1, #0xD
 +
RAM:000000D8  MOVS    R2, #0
 +
RAM:000000DA  MOVS    R3, #0xD
 +
RAM:000000DC  PUSH    {R0-R3}
 +
RAM:000000DE  LDR    R4, =0x40004164
 +
RAM:000000E0  PUSH    {R2,R4}
 +
RAM:000000E2  ADRL    R4, (loc_EC+1)
 +
RAM:000000E6  MOV    LR, R4
 +
RAM:000000E8  LDR    R4, =0x105A19
 +
RAM:000000EA  BX      R4
 +
RAM:000000EC
 +
RAM:000000EC loc_EC                                  ; DATA XREF: sub_9E+44↑o
 +
RAM:000000EC  ADD    SP, SP, #8
 +
RAM:000000EE  POP    {R0-R3}
 +
RAM:000000F0  ADDS    R0, #1
 +
RAM:000000F2  CMP    R0, #1
 +
RAM:000000F4  BEQ    loc_D6
 +
RAM:000000F6  MOV    LR, R5
 +
RAM:000000F8  LDR    R0, =0x4000FC20
 +
RAM:000000FA  MOV    R8, R0
 +
RAM:000000FC  B      loc_50
 +
RAM:000000FC ; End of function sub_9E
 +
RAM:000000FC
 +
RAM:000000FE
 +
RAM:000000FE ; =============== S U B R O U T I N E =======================================
 +
RAM:000000FE
 +
RAM:000000FE
 +
RAM:000000FE sub_FE
 +
RAM:000000FE  POP    {R2}
 +
RAM:00000100  MOV    R4, SP
 +
RAM:00000102  SUBS    R4, R4, R0
 +
RAM:00000104  BLS    loc_10C
 +
RAM:00000106  CMP    R4, R2
 +
RAM:00000108  BCS    loc_118
 +
RAM:0000010A  B      loc_116
 +
RAM:0000010C ; ---------------------------------------------------------------------------
 +
RAM:0000010C
 +
RAM:0000010C loc_10C                                ; CODE XREF: sub_FE+6↑j
 +
RAM:0000010C  LDR    R4, =0x4000BE68
 +
RAM:0000010E  SUBS    R4, R4, R0
 +
RAM:00000110  BLS    loc_118
 +
RAM:00000112  CMP    R4, R2
 +
RAM:00000114  BCS    loc_118
 +
RAM:00000116
 +
RAM:00000116 loc_116                                ; CODE XREF: sub_FE+C↑j
 +
RAM:00000116  ADDS    R2, R4, #0
 +
RAM:00000118
 +
RAM:00000118 loc_118                                ; CODE XREF: sub_FE+A↑j
 +
RAM:00000118                                        ; sub_FE+12↑j ...
 +
RAM:00000118  SUBS    R3, R0, R1
 +
RAM:0000011A  BX      LR
 +
RAM:0000011A ; End of function sub_FE
 +
RAM:0000011A
 +
RAM:0000011C
 +
RAM:0000011C ; =============== S U B R O U T I N E =======================================
 +
RAM:0000011C
 +
RAM:0000011C
 +
RAM:0000011C sub_11C                                ; 9: 0x10d1df6a 0x001021a2 0x0000df6a : svc #0x6a (offset 0x11c)
 +
RAM:0000011C  SUBS    R3, #5
 +
RAM:0000011E  MOVS    R2, #0xF0
 +
RAM:00000120  BICS    R2, R3
 +
RAM:00000122  B      loc_50
 +
RAM:00000122 ; End of function sub_11C
 +
RAM:00000122
 +
RAM:00000122 ; ---------------------------------------------------------------------------
 +
RAM:00000124 dword_124      DCD 0x4000FC20          ; DATA XREF: sub_54+4↑r
 +
RAM:00000124                                        ; sub_9E+5A↑r
 +
RAM:00000128 dword_128      DCD 0x40040000          ; DATA XREF: sub_54+6↑r
 +
RAM:0000012C dword_12C      DCD 0xEAFFFFFE          ; DATA XREF: sub_54+8↑r
 +
RAM:00000130 off_130        DCD 0x1002A0            ; DATA XREF: sub_8E:loc_6E↑r
 +
RAM:00000134 dword_134      DCD 0x5A55F0E1          ; DATA XREF: sub_86+2↑r
 +
RAM:00000134                                        ; sub_8E+2↑r
 +
RAM:00000138 dword_138      DCD 0x7000F900          ; DATA XREF: sub_9E↑r
 +
RAM:0000013C off_13C        DCD 0x7001231C          ; DATA XREF: sub_9E+8↑r
 +
RAM:00000140 off_140        DCD 0x7041231C          ; DATA XREF: sub_9E+A↑r
 +
RAM:00000144 dword_144      DCD 0x40004164          ; DATA XREF: sub_9E+40↑r
 +
RAM:00000148 off_148        DCD 0x105A19            ; DATA XREF: sub_9E+4A↑r
 +
RAM:0000014C dword_14C      DCD 0x4000BE68          ; DATA XREF: sub_FE:loc_10C↑r
 +
RAM:0000014C ; RAM          ends
 +
</syntaxhighlight>
 +
 
 +
==== First IROM patch ====
 +
This patch is applied to the bootrom IPATCH handling function so that more patches can be loaded from fuses.
 +
 
 +
<syntaxhighlight lang="c">
 +
if (patch_start_addr == 0xAF) {
 +
    patch_start_addr = 0xFF;
 +
}
 +
 +
patch_start_addr--;
 +
 +
return;
 +
</syntaxhighlight>
 +
 
 +
==== IROM patch 0 ====
 +
This patch initializes all unused IRAM memory to 0xEAFFFFFE (infinite loop instruction).
 +
 
 +
<syntaxhighlight lang="c">
 +
/*
 +
    Untranslated instructions:
 +
 +
    MOVS    R3, #7
 +
    PUSH    {R0,R1,R3-R6}
 +
*/
 +
 +
for (u32 addr = 0x4000FC20; addr < 0x40040000; addr += 0x04) {
 +
    *(u32 *)addr = 0xEAFFFFFE;
 +
}
 +
 +
/*
 +
    Untranslated instructions:
 +
 +
    POP    {R0,R1,R3-R6}
 +
*/
 +
 +
return;
 +
</syntaxhighlight>
 +
 
 +
= Anti-downgrade =
 +
The first bootloader verifies [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]] to prevent downgrading.
 +
How many fuses are expected to be burnt depends the device's unit type as below.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! System version
 +
! Expected number of burnt fuses (retail)
 +
! Expected number of burnt fuses (non-retail)
 +
|-
 +
| 1.0.0
 
| 1
 
| 1
 
| 0
 
| 0
Line 1,735: Line 3,640:  
| 1
 
| 1
 
|-
 
|-
| 9.0.0
+
| 9.0.0-9.0.1
 
| 11
 
| 11
 +
| 1
 +
|-
 +
| 9.1.0-9.2.0
 +
| 12
 +
| 1
 +
|-
 +
| 10.0.0-10.0.4
 +
| 13
 
| 1
 
| 1
 
|}
 
|}
Line 1,742: Line 3,655:  
If too many fuses are burnt the bootloader will panic immediately.
 
If too many fuses are burnt the bootloader will panic immediately.
   −
If too few are burnt, the bootloader will enable fuse programming and write the expected value to fuse indexes 0x3A and 0x3C. Afterwards, fuse programming is disabled and the panic value 0x21 is written to PMC_SCRATCH200 register (0x7000EC40). Finally, the watchdog timer is initialized and programmed to force a reset.
+
If too few are burnt, the bootloader will enable fuse programming and write the expected value to fuses [[#reserved_odm6|reserved_odm6]] and [[#reserved_odm7|reserved_odm7]]. Afterwards, fuse programming is disabled and the panic value 0x21 is written to PMC_SCRATCH200 register (0x7000EC40). Finally, the watchdog timer is initialized and programmed to force a reset.
    
On a subsequent boot, after the anti-downgrade fuses are checked again, the PMC_RST_STATUS register (0x7000E5B4) is checked and if set to 0x01 (watchdog reset) the PMC_SCRATCH200 register (0x7000EC40) will be checked for the panic value 0x21.
 
On a subsequent boot, after the anti-downgrade fuses are checked again, the PMC_RST_STATUS register (0x7000E5B4) is checked and if set to 0x01 (watchdog reset) the PMC_SCRATCH200 register (0x7000EC40) will be checked for the panic value 0x21.
 
PMC_RST_STATUS will only be set back to 0 (power on reset) if the fuse count matches the new expected value, otherwise the system will panic.
 
PMC_RST_STATUS will only be set back to 0 (power on reset) if the fuse count matches the new expected value, otherwise the system will panic.

Navigation menu