Changes

Jump to navigation Jump to search
17,154 bytes added ,  18:49, 12 December 2019
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 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.
   −
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 from 0x7000F800 to 0x7000F800 + 0xFF can be used to directly program the hardware fuse bitmap, 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 ==
 
== Registers ==
Line 11: Line 11:  
!  Address
 
!  Address
 
|-
 
|-
| [[#FUSE_CTRL|FUSE_CTRL]]
+
| [[#FUSE_FUSECTRL|FUSE_FUSECTRL]]
 
| 0x7000F800
 
| 0x7000F800
 
|-
 
|-
| [[#FUSE_REG_ADDR|FUSE_REG_ADDR]]
+
| [[#FUSE_FUSEADDR|FUSE_FUSEADDR]]
 
| 0x7000F804
 
| 0x7000F804
 
|-
 
|-
| [[#FUSE_REG_READ|FUSE_REG_READ]]
+
| [[#FUSE_FUSERDATA|FUSE_FUSERDATA]]
 
| 0x7000F808
 
| 0x7000F808
 
|-
 
|-
| [[#FUSE_REG_WRITE|FUSE_REG_WRITE]]
+
| [[#FUSE_FUSEWDATA|FUSE_FUSEWDATA]]
 
| 0x7000F80C
 
| 0x7000F80C
 
|-
 
|-
| FUSE_TIME_RD1
+
| [[#FUSE_FUSETIME_RD1|FUSE_FUSETIME_RD1]]
 
| 0x7000F810
 
| 0x7000F810
 
|-
 
|-
| FUSE_TIME_RD2
+
| [[#FUSE_FUSETIME_RD2|FUSE_FUSETIME_RD2]]
 
| 0x7000F814
 
| 0x7000F814
 
|-
 
|-
| FUSE_TIME_PGM1
+
| [[#FUSE_FUSETIME_PGM1|FUSE_FUSETIME_PGM1]]
 
| 0x7000F818
 
| 0x7000F818
 
|-
 
|-
| [[#FUSE_TIME_PGM2|FUSE_TIME_PGM2]]
+
| [[#FUSE_FUSETIME_PGM2|FUSE_FUSETIME_PGM2]]
 
| 0x7000F81C
 
| 0x7000F81C
 
|-
 
|-
| [[#FUSE_PRIV2INTFC|FUSE_PRIV2INTFC]]
+
| [[#FUSE_PRIV2INTFC_START|FUSE_PRIV2INTFC_START]]
 
| 0x7000F820
 
| 0x7000F820
 
|-
 
|-
| FUSE_FUSEBYPASS
+
| [[#FUSE_FUSEBYPASS|FUSE_FUSEBYPASS]]
 
| 0x7000F824
 
| 0x7000F824
 
|-
 
|-
| FUSE_PRIVATEKEYDISABLE
+
| [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]]
 
| 0x7000F828
 
| 0x7000F828
 
|-
 
|-
| [[#FUSE_DIS_PGM|FUSE_DIS_PGM]]
+
| [[#FUSE_DISABLEREGPROGRAM|FUSE_DISABLEREGPROGRAM]]
 
| 0x7000F82C
 
| 0x7000F82C
 
|-
 
|-
| [[#FUSE_WRITE_ACCESS|FUSE_WRITE_ACCESS]]
+
| [[#FUSE_WRITE_ACCESS_SW|FUSE_WRITE_ACCESS_SW]]
 
| 0x7000F830
 
| 0x7000F830
 
|-
 
|-
| FUSE_PWR_GOOD_SW
+
| [[#FUSE_PWR_GOOD_SW|FUSE_PWR_GOOD_SW]]
 
| 0x7000F834
 
| 0x7000F834
 +
|-
 +
| [[#FUSE_PRIV2RESHIFT|FUSE_PRIV2RESHIFT]]
 +
| 0x7000F83C
 +
|-
 +
| [[#FUSE_FUSETIME_RD3|FUSE_FUSETIME_RD3]]
 +
| 0x7000F84C
 +
|-
 +
| [[#FUSE_PRIVATE_KEY0_NONZERO|FUSE_PRIVATE_KEY0_NONZERO]]
 +
| 0x7000F880
 +
|-
 +
| [[#FUSE_PRIVATE_KEY1_NONZERO|FUSE_PRIVATE_KEY1_NONZERO]]
 +
| 0x7000F884
 +
|-
 +
| [[#FUSE_PRIVATE_KEY2_NONZERO|FUSE_PRIVATE_KEY2_NONZERO]]
 +
| 0x7000F888
 +
|-
 +
| [[#FUSE_PRIVATE_KEY3_NONZERO|FUSE_PRIVATE_KEY3_NONZERO]]
 +
| 0x7000F88C
 +
|-
 +
| [[#FUSE_PRIVATE_KEY4_NONZERO|FUSE_PRIVATE_KEY4_NONZERO]]
 +
| 0x7000F890
 
|}
 
|}
   −
==== FUSE_CTRL ====
+
==== FUSE_FUSECTRL ====
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  Bits
 
!  Bits
Line 60: Line 81:  
|-
 
|-
 
| 0-1
 
| 0-1
| Fuse command (1 = FUSE_READ; 2 = FUSE_WRITE; 3 = FUSE_SENSE)
+
| FUSE_FUSECTRL_CMD
 +
0x00: IDLE
 +
0x01: READ
 +
0x02: WRITE
 +
0x03: SENSE_CTRL
 
|-
 
|-
 
| 16-20
 
| 16-20
| Fuse state (4 = STATE_IDLE)
+
| FUSE_FUSECTRL_STATE
 +
0x00: STATE_RESET
 +
0x01: STATE_POST_RESET
 +
0x02: STATE_LOAD_ROW0
 +
0x03: STATE_LOAD_ROW1
 +
0x04: STATE_IDLE
 +
0x05: STATE_READ_SETUP
 +
0x06: STATE_READ_STROBE
 +
0x07: STATE_SAMPLE_FUSES
 +
0x08: STATE_READ_HOLD
 +
0x09: STATE_FUSE_SRC_SETUP
 +
0x0A: STATE_WRITE_SETUP
 +
0x0B: STATE_WRITE_ADDR_SETUP
 +
0x0C: STATE_WRITE_PROGRAM
 +
0x0D: STATE_WRITE_ADDR_HOLD
 +
0x0E: STATE_FUSE_SRC_HOLD
 +
0x0F: STATE_LOAD_RIR
 +
0x10: STATE_READ_BEFORE_WRITE_SETUP
 +
0x11: STATE_READ_DEASSERT_PD
 +
|-
 +
| 21
 +
| FUSE_FUSECTRL_MARGIN_READ
 +
|-
 +
| 22
 +
| FUSE_FUSECTRL_RWL
 +
|-
 +
| 23
 +
| FUSE_FUSECTRL_TRCS
 +
|-
 +
| 24
 +
| FUSE_FUSECTRL_AT1
 +
|-
 +
| 25
 +
| FUSE_FUSECTRL_AT0
 
|-
 
|-
 
| 26
 
| 26
| Fuse power down mode flag (FUSE_CTRL_PD)
+
| FUSE_FUSECTRL_PD_CTRL
 
|-
 
|-
 
| 30
 
| 30
| Fuse sense status (FUSE_CTRL_SENSE_DONE)
+
| FUSE_FUSECTRL_FUSE_SENSE_DONE
 +
|-
 +
| 31
 +
| FUSE_FUSECTRL_RECORD_SHIFT_DONE
 +
|}
 +
 
 +
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]].
 +
 
 +
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_FUSECTRL_PD_CTRL controls the fuse macro's power down mode.
 +
 
 +
FUSE_FUSECTRL_FUSE_SENSE_DONE is set if fuse sensing is completed.
 +
 
 +
FUSE_FUSECTRL_RECORD_SHIFT_DONE is set if ramrepair shift is completed.
 +
 
 +
==== FUSE_FUSEADDR ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-7
 +
| FUSE_FUSEADDR_VLDFLD
 +
|}
 +
 
 +
Takes the address of the fuse to be read/written/sensed.
 +
 
 +
==== FUSE_FUSERDATA ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-31
 +
| FUSE_FUSERDATA_DATA
 +
|}
 +
 
 +
Returns the value read from the fuse.
 +
 
 +
==== FUSE_FUSEWDATA ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-31
 +
| FUSE_FUSEWDATA_DATA
 +
|}
 +
 
 +
Takes the value to be written to the fuse.
 +
 
 +
==== FUSE_FUSETIME_RD1 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-7
 +
| FUSE_FUSETIME_RD1_TSUR_MAX
 +
|-
 +
| 8-15
 +
| FUSE_FUSETIME_RD1_TSUR_FUSEOUT
 +
|-
 +
| 16-23
 +
| 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
 +
|-
 +
| 0-15
 +
| 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
 +
|-
 +
| 0-7
 +
| FUSE_FUSETIME_PGM1_TSUP_MAX
 +
|-
 +
| 8-15
 +
| FUSE_FUSETIME_PGM1_TSUP_ADDR
 +
|-
 +
| 16-23
 +
| FUSE_FUSETIME_PGM1_THP_ADDR
 +
|-
 +
| 24-31
 +
| FUSE_FUSETIME_PGM1_THP_PS
 
|}
 
|}
   −
Before fuse reading/writing the power down mode must be disabled.
+
FUSE_FUSETIME_PGM1_TSUP_MAX takes the maximum time for [[#FUSE_FUSECTRL|STATE_WRITE_SETUP]].
FUSE_SENSE mode flushes programmed values into the [[Fuses#Cache_registers|cache registers]].
     −
==== FUSE_REG_ADDR ====
+
FUSE_FUSETIME_PGM1_TSUP_ADDR takes the time to spend on [[#FUSE_FUSECTRL|STATE_WRITE_ADDR_SETUP]].
This register takes the address of the fuse to be read/written/sensed.
     −
==== FUSE_REG_READ ====
+
FUSE_FUSETIME_PGM1_THP_ADDR takes the time to spend on [[#FUSE_FUSECTRL|STATE_WRITE_ADDR_HOLD]].
This register receives the value read from the fuse.
     −
==== FUSE_REG_WRITE ====
+
FUSE_FUSETIME_PGM1_THP_PS takes the time to spend on [[#FUSE_FUSECTRL|STATE_FUSE_SRC_HOLD]].
This register takes the value to be written to the fuse.
     −
==== FUSE_TIME_PGM2 ====
+
==== FUSE_FUSETIME_PGM2 ====
This register takes the fuse programming pulse (0xC0 == 19200 kHz).
+
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-15
 +
| FUSE_FUSETIME_PGM2_TWIDTH_PGM
 +
|-
 +
| 16-23
 +
| FUSE_FUSETIME_PGM2_TSUP_PS
 +
|-
 +
| 24-31
 +
| FUSE_FUSETIME_PGM2_THP_CSPS
 +
|}
 +
 
 +
FUSE_FUSETIME_PGM2_TWIDTH_PGM takes the program strobe pulse width used during [[#FUSE_FUSECTRL|STATE_WRITE_PROGRAM]].
   −
==== FUSE_PRIV2INTFC ====
+
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"
 
{| class="wikitable" border="1"
 
!  Bits
 
!  Bits
Line 93: Line 265:  
|-
 
|-
 
| 0
 
| 0
| FUSE_PRIV2INTFC_SDATA
+
| FUSE_PRIV2INTFC_START_DATA
 
|-
 
|-
 
| 1
 
| 1
Line 99: Line 271:  
|}
 
|}
   −
==== FUSE_DIS_PGM ====
+
Controls the interface between the internal fuse chip (INTFC) and the fuse cache registers (PRIV).
If set to 0x01, this register disables fuse programming.
+
 
 +
==== FUSE_FUSEBYPASS ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| 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
 +
|-
 +
| 0
 +
| FUSE_PRIVATEKEYDISABLE_VAL
 +
|-
 +
| 4
 +
| FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT_VAL
 +
|}
 +
 
 +
If set, this register hides the [[#Bitmap|private_key]] fuses until the next reset.
 +
 
 +
==== FUSE_DISABLEREGPROGRAM ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_DISABLEREGPROGRAM_VAL
 +
|}
 +
 
 +
If set, this register disables fuse programming until the next reset.
 +
 
 +
==== FUSE_WRITE_ACCESS_SW ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_WRITE_ACCESS_SW_CTRL
 +
|-
 +
| 16
 +
| FUSE_WRITE_ACCESS_SW_STATUS
 +
|}
 +
 
 +
Controls and returns the status of software writes to the fuse cache registers.
 +
 
 +
==== FUSE_PWR_GOOD_SW ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PWR_GOOD_SW_VAL
 +
|}
 +
 
 +
This register is deprecated and has no effect.
 +
 
 +
==== FUSE_PRIV2RESHIFT ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PRIV2RESHIFT_TRIGENABLE_VAL
 +
|-
 +
| 1
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU0_VAL
 +
|-
 +
| 2
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU1_VAL
 +
|-
 +
| 3
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU2_VAL
 +
|-
 +
| 4
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FCPU3_VAL
 +
|-
 +
| 5
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK0_VAL
 +
|-
 +
| 6
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK1_VAL
 +
|-
 +
| 7
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK2_VAL
 +
|-
 +
| 8
 +
| FUSE_PRIV2RESHIFT_TRIG_1_FL2_TBANK3_VAL
 +
|-
 +
| 9
 +
| FUSE_PRIV2RESHIFT_TRIG_1_SCPU_VAL
 +
|-
 +
| 10
 +
| FUSE_PRIV2RESHIFT_TRIG_1_SL2_TBANK_VAL
 +
|-
 +
| 11
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU0_VAL
 +
|-
 +
| 12
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU1_VAL
 +
|-
 +
| 13
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU2_VAL
 +
|-
 +
| 14
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FCPU3_VAL
 +
|-
 +
| 15
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK0_VAL
 +
|-
 +
| 16
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK1_VAL
 +
|-
 +
| 17
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK2_VAL
 +
|-
 +
| 18
 +
| FUSE_PRIV2RESHIFT_STATUS_1_FL2_TBANK3_VAL
 +
|-
 +
| 19
 +
| FUSE_PRIV2RESHIFT_STATUS_1_SCPU_VAL
 +
|-
 +
| 20
 +
| FUSE_PRIV2RESHIFT_STATUS_1_SL2_TBANK_VAL
 +
|}
 +
 
 +
Controls and returns the status of the RESHIFT hardware block used in RAM repair.
 +
 
 +
==== FUSE_FUSETIME_RD3 ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-15
 +
| 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
 +
|-
 +
| 0
 +
| FUSE_PRIVATE_KEY0_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key0]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY1_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PRIVATE_KEY1_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key1]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY2_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PRIVATE_KEY2_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key2]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY3_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PRIVATE_KEY3_NONZERO_DATA
 +
|}
 +
 
 +
Returns whether [[#Bitmap|private_key3]] is empty or not.
 +
 
 +
==== FUSE_PRIVATE_KEY4_NONZERO ====
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| FUSE_PRIVATE_KEY4_NONZERO_DATA
 +
|}
   −
==== FUSE_WRITE_ACCESS ====
+
Returns whether [[#Bitmap|private_key4]] is empty or not.
If set to 0x01, this register disables software writes to the fuse driver registers.
      
=== Cache registers ===
 
=== Cache registers ===
Line 112: Line 478:  
| FUSE_PRODUCTION_MODE
 
| FUSE_PRODUCTION_MODE
 
| 0x7000F900
 
| 0x7000F900
 +
|-
 +
| FUSE_JTAG_SECUREID_VALID
 +
| 0x7000F904
 
|-
 
|-
 
| FUSE_ODM_LOCK
 
| FUSE_ODM_LOCK
 
| 0x7000F908
 
| 0x7000F908
 +
|-
 +
| FUSE_OPT_OPENGL_EN
 +
| 0x7000F90C
 
|-
 
|-
 
| [[#FUSE_SKU_INFO|FUSE_SKU_INFO]]
 
| [[#FUSE_SKU_INFO|FUSE_SKU_INFO]]
 
| 0x7000F910
 
| 0x7000F910
 
|-
 
|-
| FUSE_CPU_SPEEDO_0
+
| FUSE_CPU_SPEEDO_0_CALIB
 
| 0x7000F914
 
| 0x7000F914
 
|-
 
|-
| FUSE_CPU_IDDQ
+
| FUSE_CPU_IDDQ_CALIB
 
| 0x7000F918
 
| 0x7000F918
 
|-
 
|-
| FUSE_FT_REV
+
| FUSE_DAC_CRT_CALIB
 +
| 0x7000F91C
 +
|-
 +
| FUSE_DAC_HDTV_CALIB
 +
| 0x7000F920
 +
|-
 +
| FUSE_DAC_SDTV_CALIB
 +
| 0x7000F924
 +
|-
 +
| [[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]]
 
| 0x7000F928
 
| 0x7000F928
 
|-
 
|-
| FUSE_CPU_SPEEDO_1
+
| FUSE_CPU_SPEEDO_1_CALIB
 
| 0x7000F92C
 
| 0x7000F92C
 
|-
 
|-
| FUSE_CPU_SPEEDO_2
+
| FUSE_CPU_SPEEDO_2_CALIB
 
| 0x7000F930
 
| 0x7000F930
 
|-
 
|-
| FUSE_SOC_SPEEDO_0
+
| FUSE_SOC_SPEEDO_0_CALIB
 
| 0x7000F934
 
| 0x7000F934
 
|-
 
|-
| [[#FUSE_SOC_SPEEDO_1|FUSE_SOC_SPEEDO_1]]
+
| [[#FUSE_SOC_SPEEDO_1_CALIB|FUSE_SOC_SPEEDO_1_CALIB]]
 
| 0x7000F938
 
| 0x7000F938
 
|-
 
|-
| FUSE_SOC_SPEEDO_2
+
| FUSE_SOC_SPEEDO_2_CALIB
 
| 0x7000F93C
 
| 0x7000F93C
 
|-
 
|-
| FUSE_SOC_IDDQ
+
| FUSE_SOC_IDDQ_CALIB
 
| 0x7000F940
 
| 0x7000F940
 +
|-
 +
| FUSE_RESERVED_PRODUCTION_WP
 +
| 0x7000F944
 
|-
 
|-
 
| [[#FUSE_FA|FUSE_FA]]
 
| [[#FUSE_FA|FUSE_FA]]
 
| 0x7000F948
 
| 0x7000F948
 +
|-
 +
| FUSE_RESERVED_PRODUCTION
 +
| 0x7000F94C
 +
|-
 +
| FUSE_HDMI_LANE0_CALIB
 +
| 0x7000F950
 +
|-
 +
| FUSE_HDMI_LANE1_CALIB
 +
| 0x7000F954
 +
|-
 +
| FUSE_HDMI_LANE2_CALIB
 +
| 0x7000F958
 +
|-
 +
| FUSE_HDMI_LANE3_CALIB
 +
| 0x7000F95C
 +
|-
 +
| FUSE_ENCRYPTION_RATE
 +
| 0x7000F960
 
|-
 
|-
 
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY0]]
 
| [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY0]]
Line 173: Line 575:  
| 0x7000F980
 
| 0x7000F980
 
|-
 
|-
| FUSE_TSENSOR_1
+
| FUSE_TSENSOR1_CALIB
 
| 0x7000F984
 
| 0x7000F984
 
|-
 
|-
| FUSE_TSENSOR_2
+
| FUSE_TSENSOR2_CALIB
 
| 0x7000F988
 
| 0x7000F988
 
|-
 
|-
| FUSE_CP_REV
+
| FUSE_VSENSOR_CALIB
 +
| 0x7000F98C
 +
|-
 +
| [[#FUSE_OPT_CP_REV|FUSE_OPT_CP_REV]]
 
| 0x7000F990
 
| 0x7000F990
 
|-
 
|-
| FUSE_TSENSOR_0
+
| FUSE_OPT_PFG
 +
| 0x7000F994
 +
|-
 +
| FUSE_TSENSOR0_CALIB
 
| 0x7000F998
 
| 0x7000F998
 
|-
 
|-
| FUSE_FIRST_BOOTROM_PATCH_SIZE_REG
+
| FUSE_FIRST_BOOTROM_PATCH_SIZE
 
| 0x7000F99C
 
| 0x7000F99C
 
|-
 
|-
Line 206: Line 614:  
| 0x7000F9B4
 
| 0x7000F9B4
 
|-
 
|-
| FUSE_ARM_JTAG_DISABLE
+
| FUSE_ARM_JTAG_DIS
 
| 0x7000F9B8
 
| 0x7000F9B8
 
|-
 
|-
Line 215: Line 623:  
| 0x7000F9C0
 
| 0x7000F9C0
 
|-
 
|-
| FUSE_VP8_ENABLE
+
| FUSE_OPT_VP9_DISABLE
 
| 0x7000F9C4
 
| 0x7000F9C4
 
|-
 
|-
Line 242: Line 650:  
| 0x7000F9E4
 
| 0x7000F9E4
 
|-
 
|-
| FUSE_SKU_USB_CALIB
+
| FUSE_OBS_DIS
 +
| 0x7000F9E8
 +
|-
 +
| FUSE_NOR_INFO
 +
| 0x7000F9EC
 +
|-
 +
| FUSE_USB_CALIB
 
| 0x7000F9F0
 
| 0x7000F9F0
 
|-
 
|-
Line 248: Line 662:  
| 0x7000F9F4
 
| 0x7000F9F4
 
|-
 
|-
| FUSE_VENDOR_CODE
+
| FUSE_KFUSE_PRIVKEY_CTRL
 +
| 0x7000F9F8
 +
|-
 +
| FUSE_PACKAGE_INFO
 +
| 0x7000F9FC
 +
|-
 +
| FUSE_OPT_VENDOR_CODE
 
| 0x7000FA00
 
| 0x7000FA00
 
|-
 
|-
| FUSE_FAB_CODE
+
| FUSE_OPT_FAB_CODE
 
| 0x7000FA04
 
| 0x7000FA04
 
|-
 
|-
| FUSE_LOT_CODE_0
+
| FUSE_OPT_LOT_CODE_0
 
| 0x7000FA08
 
| 0x7000FA08
 
|-
 
|-
| FUSE_LOT_CODE_1
+
| FUSE_OPT_LOT_CODE_1
 
| 0x7000FA0C
 
| 0x7000FA0C
 
|-
 
|-
| FUSE_WAFER_ID
+
| FUSE_OPT_WAFER_ID
 
| 0x7000FA10
 
| 0x7000FA10
 
|-
 
|-
| FUSE_X_COORDINATE
+
| FUSE_OPT_X_COORDINATE
 
| 0x7000FA14
 
| 0x7000FA14
 
|-
 
|-
| FUSE_Y_COORDINATE
+
| FUSE_OPT_Y_COORDINATE
 
| 0x7000FA18
 
| 0x7000FA18
 +
|-
 +
| [[#FUSE_OPT_SEC_DEBUG_EN|FUSE_OPT_SEC_DEBUG_EN]]
 +
| 0x7000FA1C
 +
|-
 +
| FUSE_OPT_OPS_RESERVED
 +
| 0x7000FA20
 
|-
 
|-
 
| FUSE_SATA_CALIB
 
| FUSE_SATA_CALIB
 
| 0x7000FA24
 
| 0x7000FA24
 
|-
 
|-
| FUSE_GPU_IDDQ
+
| FUSE_GPU_IDDQ_CALIB
 
| 0x7000FA28
 
| 0x7000FA28
 
|-
 
|-
| FUSE_TSENSOR_3
+
| FUSE_TSENSOR3_CALIB
 
| 0x7000FA2C
 
| 0x7000FA2C
 +
|-
 +
| FUSE_SKU_BOND_OUT_L
 +
| 0x7000FA30
 +
|-
 +
| FUSE_SKU_BOND_OUT_H
 +
| 0x7000FA34
 +
|-
 +
| FUSE_SKU_BOND_OUT_U
 +
| 0x7000FA38
 +
|-
 +
| FUSE_SKU_BOND_OUT_V
 +
| 0x7000FA3C
 +
|-
 +
| FUSE_SKU_BOND_OUT_W
 +
| 0x7000FA40
 +
|-
 +
| FUSE_OPT_SAMPLE_TYPE
 +
| 0x7000FA44
 
|-
 
|-
 
| FUSE_OPT_SUBREVISION
 
| FUSE_OPT_SUBREVISION
 
| 0x7000FA48
 
| 0x7000FA48
 
|-
 
|-
| FUSE_TSENSOR_4
+
| FUSE_OPT_SW_RESERVED_0
 +
| 0x7000FA4C
 +
|-
 +
| FUSE_OPT_SW_RESERVED_1
 +
| 0x7000FA50
 +
|-
 +
| FUSE_TSENSOR4_CALIB
 
| 0x7000FA54
 
| 0x7000FA54
 
|-
 
|-
| FUSE_TSENSOR_5
+
| FUSE_TSENSOR5_CALIB
 
| 0x7000FA58
 
| 0x7000FA58
 
|-
 
|-
| FUSE_TSENSOR_6
+
| FUSE_TSENSOR6_CALIB
 
| 0x7000FA5C
 
| 0x7000FA5C
 
|-
 
|-
| FUSE_TSENSOR_7
+
| FUSE_TSENSOR7_CALIB
 
| 0x7000FA60
 
| 0x7000FA60
 
|-
 
|-
| FUSE_OPT_PRIV_SEC_DIS
+
| [[#FUSE_OPT_PRIV_SEC_EN|FUSE_OPT_PRIV_SEC_EN]]
 
| 0x7000FA64
 
| 0x7000FA64
 
|-
 
|-
 
| [[#FUSE_PKC_DISABLE|FUSE_PKC_DISABLE]]
 
| [[#FUSE_PKC_DISABLE|FUSE_PKC_DISABLE]]
 
| 0x7000FA68
 
| 0x7000FA68
 +
|-
 +
| FUSE_FUSE2TSEC_DEBUG_DISABLE
 +
| 0x7000FA7C
 
|-
 
|-
 
| FUSE_TSENSOR_COMMON
 
| FUSE_TSENSOR_COMMON
 
| 0x7000FA80
 
| 0x7000FA80
 
|-
 
|-
| FUSE_DEBUG_AUTH_OVERRIDE
+
| FUSE_OPT_CP_BIN
 +
| 0x7000FA84
 +
|-
 +
| FUSE_OPT_GPU_DISABLE
 +
| 0x7000FA88
 +
|-
 +
| FUSE_OPT_FT_BIN
 +
| 0x7000FA8C
 +
|-
 +
| FUSE_OPT_DONE_MAP
 +
| 0x7000FA90
 +
|-
 +
| FUSE_APB2JTAG_DISABLE
 +
| 0x7000FA98
 +
|-
 +
| FUSE_ODM_INFO
 
| 0x7000FA9C
 
| 0x7000FA9C
 
|-
 
|-
| FUSE_TSENSOR_8
+
| FUSE_ARM_CRYPT_DE_FEATURE
 +
| 0x7000FAA8
 +
|-
 +
| FUSE_WOA_SKU_FLAG
 +
| 0x7000FAC0
 +
|-
 +
| FUSE_ECO_RESERVE_1
 +
| 0x7000FAC4
 +
|-
 +
| FUSE_GCPLEX_CONFIG_FUSE
 +
| 0x7000FAC8
 +
|-
 +
| FUSE_PRODUCTION_MONTH
 +
| 0x7000FACC
 +
|-
 +
| FUSE_RAM_REPAIR_INDICATOR
 +
| 0x7000FAD0
 +
|-
 +
| FUSE_TSENSOR9_CALIB
 
| 0x7000FAD4
 
| 0x7000FAD4
 +
|-
 +
| FUSE_VMIN_CALIBRATION
 +
| 0x7000FADC
 +
|-
 +
| FUSE_AGING_SENSOR_CALIBRATION
 +
| 0x7000FAE0
 
|-
 
|-
 
| FUSE_DEBUG_AUTHENTICATION
 
| FUSE_DEBUG_AUTHENTICATION
Line 314: Line 806:  
| 0x7000FAE8
 
| 0x7000FAE8
 
|-
 
|-
| FUSE_AID
+
| FUSE_SECURE_PROVISION_INFO
 +
| 0x7000FAEC
 +
|-
 +
| FUSE_OPT_GPU_DISABLE_CP1
 +
| 0x7000FAF0
 +
|-
 +
| FUSE_SPARE_ENDIS
 +
| 0x7000FAF4
 +
|-
 +
| [[#FUSE_ECO_RESERVE_0|FUSE_ECO_RESERVE_0]]
 
| 0x7000FAF8
 
| 0x7000FAF8
 
|-
 
|-
| FUSE_RESERVED_CALIB
+
| FUSE_RESERVED_CALIB0
 
| 0x7000FB04
 
| 0x7000FB04
 +
|-
 +
| FUSE_RESERVED_CALIB1
 +
| 0x7000FB08
 
|-
 
|-
 
| FUSE_OPT_GPU_TPC0_DISABLE
 
| FUSE_OPT_GPU_TPC0_DISABLE
 
| 0x7000FB0C
 
| 0x7000FB0C
 
|-
 
|-
| FUSE_TSENSOR_9
+
| FUSE_OPT_GPU_TPC0_DISABLE_CP1
 +
| 0x7000FB10
 +
|-
 +
| FUSE_OPT_CPU_DISABLE
 +
| 0x7000FB14
 +
|-
 +
| FUSE_OPT_CPU_DISABLE_CP1
 +
| 0x7000FB18
 +
|-
 +
| FUSE_TSENSOR10_CALIB
 
| 0x7000FB1C
 
| 0x7000FB1C
 +
|-
 +
| FUSE_TSENSOR10_CALIB_AUX
 +
| 0x7000FB20
 +
|-
 +
| FUSE_OPT_RAM_SVOP_DP
 +
| 0x7000FB24
 +
|-
 +
| FUSE_OPT_RAM_SVOP_PDP
 +
| 0x7000FB28
 +
|-
 +
| FUSE_OPT_RAM_SVOP_REG
 +
| 0x7000FB2C
 +
|-
 +
| FUSE_OPT_RAM_SVOP_SP
 +
| 0x7000FB30
 +
|-
 +
| FUSE_OPT_RAM_SVOP_SMPDP
 +
| 0x7000FB34
 +
|-
 +
| FUSE_OPT_GPU_TPC0_DISABLE_CP2
 +
| 0x7000FB38
 
|-
 
|-
 
| FUSE_OPT_GPU_TPC1_DISABLE
 
| FUSE_OPT_GPU_TPC1_DISABLE
 
| 0x7000FB3C
 
| 0x7000FB3C
 +
|-
 +
| FUSE_OPT_GPU_TPC1_DISABLE_CP1
 +
| 0x7000FB40
 +
|-
 +
| FUSE_OPT_GPU_TPC1_DISABLE_CP2
 +
| 0x7000FB44
 +
|-
 +
| FUSE_OPT_CPU_DISABLE_CP2
 +
| 0x7000FB48
 +
|-
 +
| FUSE_OPT_GPU_DISABLE_CP2
 +
| 0x7000FB4C
 
|-
 
|-
 
| FUSE_USB_CALIB_EXT
 
| FUSE_USB_CALIB_EXT
 
| 0x7000FB50
 
| 0x7000FB50
 +
|-
 +
| FUSE_RESERVED_FIELD
 +
| 0x7000FB54
 +
|-
 +
| FUSE_OPT_ECC_EN
 +
| 0x7000FB58
 +
|-
 +
| FUSE_SPARE_REALIGNMENT_REG
 +
| 0x7000FB7C
 
|-
 
|-
 
| FUSE_SPARE_BIT_0
 
| FUSE_SPARE_BIT_0
Line 431: Line 986:  
==== FUSE_SKU_INFO ====
 
==== FUSE_SKU_INFO ====
 
Stores the SKU ID (must be 0x83).
 
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_SOC_SPEEDO_1_CALIB ====
 +
Stores the bootrom patch version.
    
==== FUSE_FA ====
 
==== FUSE_FA ====
 
Stores failure analysis mode.
 
Stores failure analysis mode.
   −
==== FUSE_SOC_SPEEDO_1 ====
+
==== FUSE_PUBLIC_KEY ====
Stores the bootrom patch version.
+
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
 +
|-
 +
| 0-2
 +
| Boot device
 +
|-
 +
| 3
 +
| Skip device selection straps (0 = don't skip; 1 = skip)
 +
|-
 +
| 4
 +
| ENABLE_CHARGER_DETECT
 +
|-
 +
| 5
 +
| ENABLE_WATCHDOG
 +
|-
 +
| 6
 +
| Forced RCM two button mode (0 = Only VOLUME_UP; 1 = VOLUME_UP + HOME)
 +
|-
 +
| 7
 +
| RCM USB controller mode (0 = USB 2.0; 1 = XUSB)
 +
|}
 +
 
 +
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 ====
 
==== FUSE_RESERVED_ODM0 ====
This appears to store a hardware ID.
+
Stores an hardware ID.
    
==== FUSE_RESERVED_ODM1 ====
 
==== FUSE_RESERVED_ODM1 ====
This appears to store a hardware ID.
+
Stores an hardware ID.
    
==== FUSE_RESERVED_ODM2 ====
 
==== FUSE_RESERVED_ODM2 ====
Line 450: Line 1,051:  
|-
 
|-
 
| 0-4
 
| 0-4
| [5.0.0+] Used as key generation
+
| [5.0.0+] Used as key generation (patched units only)
 
|}
 
|}
   −
This appears to store a hardware ID.
+
Stores an hardware ID in original launch units, but in patched units it stores a single value (key generation).
    
==== FUSE_RESERVED_ODM3 ====
 
==== FUSE_RESERVED_ODM3 ====
This appears to store a hardware ID.
+
Stores an hardware ID in original launch units, but is empty in patched units.
    
==== FUSE_RESERVED_ODM4 ====
 
==== FUSE_RESERVED_ODM4 ====
Line 464: Line 1,065:  
|-
 
|-
 
| 0-1
 
| 0-1
| Unit type (3 = debug; 0 = retail)
+
| Unit type (0x00 = Retail, 0x03 = Debug)
 
|-
 
|-
 
| 2
 
| 2
| Unknown config (must be 1 on retail)
+
| Production flag (0x00 = Prototype, 0x01 = Production)
 
|-
 
|-
 
| [1.0.0-3.0.2] 3-5
 
| [1.0.0-3.0.2] 3-5
 
[4.0.0+] 3-7
 
[4.0.0+] 3-7
| DRAM id
+
| DRAM ID
 
|-
 
|-
 
| 8
 
| 8
| Unknown config mask (must be 0 on retail)
+
| Development flag (0x00 = Retail, 0x01 = Development)
 
|-
 
|-
 
| 9
 
| 9
| Unit type mask (0 = debug; 1 = retail)
+
| Unit type flag (0x00 = Debug, 0x01 = Retail)
 
|-
 
|-
 
| 10
 
| 10
| [3.0.0+] Kiosk mode (0 = retail; 1 = kiosk)
+
| [3.0.0+] Kiosk flag (0x00 = Retail, 0x01 = Kiosk/Quest)
 
|-
 
|-
 
| 11
 
| 11
| [5.0.0+] SoC variant (0 = T210; 1 = T214)
+
| [5.0.0+] Patch flag (0x00 = Unpatched, 0x01 = Patched)
 
|-
 
|-
 
| 16-19
 
| 16-19
| [4.0.0+] New unit type
+
| [4.0.0+] New hardware type (0x00 = Icosa, 0x01 = Iowa, 0x02 = Hoag)
 
|}
 
|}
   −
This stores some device configuration parameters.
+
Stores some device configuration parameters.
 +
 
 +
==== FUSE_RESERVED_ODM5 ====
 +
Empty and unused.
    
==== FUSE_RESERVED_ODM6 ====
 
==== FUSE_RESERVED_ODM6 ====
This register returns the value programmed into index 0x3A of the fuse array.  
+
Returns the value of the [[#reserved_odm6|reserved_odm6]] anti-downgrade fuse.
    
==== FUSE_RESERVED_ODM7 ====
 
==== FUSE_RESERVED_ODM7 ====
This register returns the value programmed into index 0x3C of the fuse array.
+
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 ====
 
==== FUSE_SPARE_BIT_2 ====
Stores part of the speedo fusing revision.
+
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| Speedo fusing revision
 +
|}
    
==== FUSE_SPARE_BIT_3 ====
 
==== FUSE_SPARE_BIT_3 ====
Stores part of the speedo fusing revision.
+
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| Speedo fusing revision
 +
|}
    
==== FUSE_SPARE_BIT_4 ====
 
==== FUSE_SPARE_BIT_4 ====
Stores part of the speedo fusing revision.
+
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0
 +
| Speedo fusing revision
 +
|}
    
==== FUSE_SPARE_BIT_5 ====
 
==== FUSE_SPARE_BIT_5 ====
 
Must be non-zero on retail units, otherwise the first bootloader panics.
 
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 retail master key seeds (only the last one matches the retail master key seed).
+
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.
 +
 
 +
== Bitmap ==
 +
The actual hardware fuses are stored in a bitmap and may be programmed through the fuse driver after enabling fuse programming.
   −
==== FUSE_PRIVATE_KEY ====
+
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.
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_PUBLIC_KEY ====
+
Below is a list of common fuses used by Tegra devices (and applicable to the Switch).
This stores the SHA256 hash of the 2048-bit RSA key expected at BCT+0x210.
     −
==== FUSE_RESERVED_SW ====
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 +
!  Name
 +
!  Number
 +
!  Redundant number
 
!  Bits
 
!  Bits
!  Description
   
|-
 
|-
| 0-2
+
| enable_fuse_program
| Boot device
+
| 0
 +
| 1
 +
| 0
 +
|-
 +
| disable_fuse_program
 +
| 0
 +
| 1
 +
| 1
 +
|-
 +
| bypass_fuses
 +
| 0
 +
| 1
 +
| 2
 
|-
 
|-
 +
| jtag_direct_access_disable
 +
| 0
 +
| 1
 
| 3
 
| 3
| Skip device selection straps (0 = don't skip; 1 = skip)
   
|-
 
|-
 +
| production_mode
 +
| 0
 +
| 1
 
| 4
 
| 4
| ENABLE_CHARGER_DETECT
   
|-
 
|-
 +
| jtag_secureid_valid
 +
| 0
 +
| 1
 
| 5
 
| 5
| ENABLE_WATCHDOG
   
|-
 
|-
| 6
+
| odm_lock
| Forced RCM two button mode (0 = Only VOLUME_UP; 1 = VOLUME_UP + HOME)
+
| 0
 +
| 1
 +
| 6-9
 +
|-
 +
| fa_mode
 +
| 0
 +
| 1
 +
| 10
 
|-
 
|-
| 7
+
| security_mode
| RCM USB controller mode (0 = USB 2.0; 1 = XUSB)
+
| 0
|}
+
| 1
 
+
| 11
This caches the value of the sw_reserved fuse from the hardware array.
  −
 
  −
==== FUSE_PKC_DISABLE ====
  −
This caches the value of the pkc_disable fuse from the hardware array.
  −
 
  −
== eFuses ==
  −
The actual hardware fuses can be programmed through the fuse driver after enabling fuse programming.
  −
 
  −
Below is a list of common fuse indexes used by Tegra devices (and applicable to the Switch).
  −
Note that the indexes are relative to the start of the fuse array and each element is a 4 byte word. A single fuse write operation always writes the same word at both fuse_array + 0 (PRIMARY_ALIAS) and fuse_array + 1 (REDUNDANT_ALIAS).
  −
 
  −
{| class="wikitable" border="1"
  −
!  Name
  −
!  Index
  −
!  Bits
   
|-
 
|-
| jtag_disable
+
| arm_debug_dis
| 0x00
+
| 0
 
| 1
 
| 1
 +
| 12
 
|-
 
|-
| odm_production_mode
+
| obs_dis
| 0x00
+
| 0
 
| 1
 
| 1
 +
| 13
 
|-
 
|-
| odm_lock
+
| public_key0
| 0x00
+
| 10
| 4
+
| 11
 +
| 30-31
 +
|-
 +
| public_key0
 +
| 12
 +
| 13
 +
| 0-29
 +
|-
 +
| public_key1
 +
| 12
 +
| 13
 +
| 30-31
 
|-
 
|-
| public_key
+
| public_key1
| 0x0C
+
| 14
| 256
+
| 15
 +
| 0-29
 
|-
 
|-
| secure_boot_key
+
| public_key2
| 0x22
+
| 14
| 128
+
| 15
 +
| 30-31
 
|-
 
|-
| device_key
+
| public_key2
| 0x2A
+
| 16
| 32
+
| 17
 +
| 0-29
 
|-
 
|-
| sec_boot_dev_cfg
+
| public_key3
| 0x2C
   
| 16
 
| 16
 +
| 17
 +
| 30-31
 
|-
 
|-
| sec_boot_dev_sel
+
| public_key3
| 0x2C
+
| 18
| 3
+
| 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
 
|-
 
|-
| sw_reserved
+
| opt_ops_reserved
| 0x2E
+
| 70
| 12
+
| 71
 +
| 18-23
 
|-
 
|-
| ignore_dev_sel_straps
+
| sata_calib
| 0x2E
+
| 70
| 1
+
| 71
 +
| 24-25
 
|-
 
|-
| [[#odm_reserved|odm_reserved]]
+
| opt_priv_sec_en
| 0x2E
+
| 90
| 256
+
| 91
 +
| 8
 
|-
 
|-
 
| pkc_disable
 
| pkc_disable
| 0x52
+
| 90
| 1
+
| 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
 
|-
 
|-
| debug_authentication
+
| aid
| 0x5A
+
| 103
| 5
+
| None
 +
| 2-31
 
|-
 
|-
 
| aid
 
| aid
| 0x67
+
| 104
| 32
+
| None
 +
| 0-1
 
|-
 
|-
| [[#bootrom_ipatch|bootrom_ipatch]]
+
| ramrepair_record0
| 0x72
+
| 106
| 624
+
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record1
 +
| 107
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record2
 +
| 108
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record3
 +
| 109
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record4
 +
| 110
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record5
 +
| 111
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record6
 +
| 112
 +
| None
 +
| 0-31
 +
|-
 +
| ramrepair_record7
 +
| 113
 +
| None
 +
| 0-31
 +
|-
 +
| [[#irom_patch|irom_patch]]
 +
| 114
 +
| None
 +
| Variable
 
|}
 
|}
   −
=== odm_reserved ===
+
=== reserved_odm6 ===
The first bootloader only burns fuses in this region.
+
Used for [[#Anti-downgrade|anti-downgrade]] control.
Both fuse indexes 0x3A (odm_reserved + 0x0C) and 0x3C (odm_reserved + 0x0E) are used for anti-downgrade control. These fuses will have their values cached into [[#FUSE_RESERVED_ODM6|FUSE_RESERVED_ODM6]] and [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]].
     −
=== bootrom_ipatch ===
+
=== reserved_odm7 ===
Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse array using a specific format (see [https://gist.github.com/shuffle2/f8728159da100e9df2606d43925de0af shuffle2's ipatch decoder]). The bootrom reads these fuses in order to initialize the IPATCH hardware, which allows overriding data returned for code and data fetches done by BPMP. The revision stored in FUSE_CP_REV indicates the unique set of values stored in ipatch fuses.
+
Used for [[#Anti-downgrade|anti-downgrade]] control.
 +
 
 +
=== irom_patch ===
 +
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.
    
The following represents the patch data dumped from a Switch console:
 
The following represents the patch data dumped from a Switch console:
Line 631: Line 1,770:  
RAM:00000000
 
RAM:00000000
 
RAM:00000000 irom_svc_dispatch
 
RAM:00000000 irom_svc_dispatch
RAM:00000000  STMFD  SP!, {R0-R2}                  ; ipatches:
+
RAM:00000000  STMFD  SP!, {R0-R2}                  ; ipatches (new):
 +
RAM:00000000                                        ;  0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
 +
RAM:00000000                                        ;  1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
 +
RAM:00000000                                        ;  2 3797df26    6f2e    df26 : svc #0x26 (offset 0x94)
 +
RAM:00000000                                        ;  3 3b4d2100    769a    2100 : movs r1, #0x00
 +
RAM:00000000                                        ;  4  42bdf2c      856    df2c : svc #0x2c (offset 0xa0)
 +
RAM:00000000                                        ;  5 37aadf42    6f54    df42 : svc #0x42 (offset 0xcc)
 +
RAM:00000000                                        ;  6  972df4b    12e4    df4b : svc #0x4b (offset 0xde)
 +
RAM:00000000                                        ;  7 2293df54    4526    df54 : svc #0x54 (offset 0xf0)
 +
RAM:00000000                                        ;  8 21fadf5d    43f4    df5d : svc #0x5d (offset 0x102)
 +
RAM:00000000                                        ;  9 bba2ac57    17744    ac57 : data
 +
RAM:00000000                                        ; 10 bbac3d19    17758    3d19 : data
 +
RAM:00000000                                        ; 11 1e952001    3d2a    2001 : movs r0, #0x01
 +
RAM:00000000                                        ;
 +
RAM:00000000                                        ; ipatches (old):
 
RAM:00000000                                        ;  0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
 
RAM:00000000                                        ;  0  b57df00    16ae    df00 : svc #0x00 (offset 0x48)
 
RAM:00000000                                        ;  1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
 
RAM:00000000                                        ;  1 1820df22    3040    df22 : svc #0x22 (offset 0x8c)
Line 862: Line 2,015:  
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices.
 
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices.
   −
==== ipatch 0 ====
+
==== IROM patch 0 ====
 
This patch configures clock enables and clock gate overrides for new hardware.
 
This patch configures clock enables and clock gate overrides for new hardware.
   Line 911: Line 2,064:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 1 ====
+
==== IROM patch 1 ====
 
This patch is a bugfix.
 
This patch is a bugfix.
   Line 923: Line 2,076:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 2 ====
+
==== IROM patch 2 ====
 
This patch adjusts USB configurations.
 
This patch adjusts USB configurations.
   Line 939: Line 2,092:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 3 ====
+
==== IROM patch 3 ====
This patch pertains to XHCI IRQ clearing checks and forces a result code to be 0.
+
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.
   −
==== ipatch 4 ====
+
==== IROM patch 4 ====
 
This patch allows backing up and restoring strapping options for warmboot.
 
This patch allows backing up and restoring strapping options for warmboot.
   Line 972: Line 2,127:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 5 ====
+
==== IROM patch 5 ====
 
This patch adjusts USB configurations.
 
This patch adjusts USB configurations.
   Line 989: Line 2,144:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 6 ====
+
==== IROM patch 6 ====
 
This patch is a factory backdoor.
 
This patch is a factory backdoor.
   Line 995: Line 2,150:     
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
  u32 FUSE_DEBUG_AUTH_OVERRIDE = 0x7000FA9C;
+
  u32 FUSE_ODM_INFO = 0x7000FA9C;
   −
  u32 debug_auth_override_val = *(u32 *)FUSE_DEBUG_AUTH_OVERRIDE;
+
  u32 odm_info = *(u32 *)FUSE_ODM_INFO;
  debug_auth_override_val = ((debug_auth_override_val >> 0x08) << 0x01);
+
  debug_auth_override_val = ((odm_info >> 0x08) << 0x01);
    
  // Override debug authentication value stored in IRAM
 
  // Override debug authentication value stored in IRAM
Line 1,012: Line 2,167:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 7 ====
+
==== IROM patch 7 ====
 
This patch is a bugfix.
 
This patch is a bugfix.
   Line 1,044: Line 2,199:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatch 8 ====
+
==== IROM patch 8 ====
 
This patch is a bugfix.
 
This patch is a bugfix.
   Line 1,064: Line 2,219:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==== ipatches 9 and 10 ====
+
==== IROM patches 9 and 10 ====
 
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A.
 
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A.
   −
==== ipatch 11 ====
+
==== IROM patch 11 ====
This patch pertains to the [[Security_Engine|Security Engine]] context restore process and forces SE_OPERATION_UNK1 to be 0x01.
+
This patch forces the value of [[Security_Engine|SE_TZRAM_SECURITY]] to be 0x01 instead of restoring it from the saved SE context.
    
== Anti-downgrade ==
 
== Anti-downgrade ==
Line 1,110: Line 2,265:  
| 6.2.0
 
| 6.2.0
 
| 8
 
| 8
 +
| 1
 +
|-
 +
| 7.0.0-8.0.1
 +
| 9
 +
| 1
 +
|-
 +
| 8.1.0
 +
| 10
 +
| 1
 +
|-
 +
| 9.0.0-9.0.1
 +
| 11
 +
| 1
 +
|-
 +
| 9.1.0
 +
| 12
 
| 1
 
| 1
 
|}
 
|}
Line 1,115: Line 2,286:  
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