Fuses: Difference between revisions
mNo edit summary  | 
				No edit summary  | 
				||
| (102 intermediate revisions by 9 users not shown) | |||
| Line 1: | Line 1: | ||
The Nintendo Switch   | The Nintendo Switch uses the Tegra's fuse driver for accessing one time programmable data.  | ||
Registers   | = Registers =  | ||
The fuse driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming.  | |||
==   | == Erista ==  | ||
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 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  | ||
!  Address  | !  Address  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_FUSECTRL|FUSE_FUSECTRL]]  | ||
| 0x7000F800  | | 0x7000F800  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_FUSEADDR|FUSE_FUSEADDR]]  | ||
| 0x7000F804  | | 0x7000F804  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_FUSERDATA|FUSE_FUSERDATA]]  | ||
| 0x7000F808  | | 0x7000F808  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_FUSEWDATA|FUSE_FUSEWDATA]]  | ||
| 0x7000F80C  | | 0x7000F80C  | ||
|-  | |-  | ||
|   | | [[#FUSE_FUSETIME_RD1|FUSE_FUSETIME_RD1]]  | ||
| 0x7000F810  | | 0x7000F810  | ||
|-  | |-  | ||
|   | | [[#FUSE_FUSETIME_RD2|FUSE_FUSETIME_RD2]]  | ||
| 0x7000F814  | | 0x7000F814  | ||
|-  | |-  | ||
|   | | [[#FUSE_FUSETIME_PGM1|FUSE_FUSETIME_PGM1]]  | ||
| 0x7000F818  | | 0x7000F818  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_FUSETIME_PGM2|FUSE_FUSETIME_PGM2]]  | ||
| 0x7000F81C  | | 0x7000F81C  | ||
|-  | |-  | ||
| [[#  | | [[#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_DISABLEREGPROGRAM|FUSE_DISABLEREGPROGRAM]]  | ||
| 0x7000F82C  | | 0x7000F82C  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_WRITE_ACCESS_SW|FUSE_WRITE_ACCESS_SW]]  | ||
| 0x7000F830  | | 0x7000F830  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIV2RESHIFT|FUSE_PRIV2RESHIFT]]  | ||
| FUSE_PRIV2RESHIFT  | |||
| 0x7000F83C  | | 0x7000F83C  | ||
|-  | |-  | ||
|   | | [[#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  | ||
|}  | |}  | ||
====   | ==== FUSE_FUSECTRL ====  | ||
{| class="wikitable" border="1"  | {| class="wikitable" border="1"  | ||
!  Bits  | !  Bits  | ||
| Line 81: | Line 81: | ||
|-  | |-  | ||
| 0-1  | | 0-1  | ||
|   | | FUSE_FUSECTRL_CMD  | ||
 0x00: IDLE  | |||
 0x01: READ  | |||
 0x02: WRITE  | |||
 0x03: SENSE_CTRL  | |||
|-  | |-  | ||
| 16-20  | | 16-20  | ||
|   | | 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_FUSECTRL_PD_CTRL  | ||
|-  | |-  | ||
| 30  | | 30  | ||
|   | | 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 allows accessing the RIR (redundant information row).  | |||
FUSE_FUSECTRL_TRCS allows accessing the TRCS (test rows and columns).  | |||
====   | FUSE_FUSECTRL_AT1 selects the TRCS test column (always 0).  | ||
FUSE_FUSECTRL_AT0 selects the TRCS test row (0 or 1).  | |||
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 record shifting is completed.  | |||
==== FUSE_FUSEADDR ====  | |||
{| class="wikitable" border="1"  | {| class="wikitable" border="1"  | ||
!  Bits  | !  Bits  | ||
!  Description  | !  Description  | ||
|-  | |-  | ||
| 0  | | 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"  | {| 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  | ||
|}  | |||
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  | |||
|-  | |-  | ||
|   | | 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_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  | |||
|-  | |-  | ||
|   | | 0  | ||
|   | | FUSE_PRIV2INTFC_START_DATA  | ||
|-  | |-  | ||
|   | | 1  | ||
|   | | 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  | |||
|-  | |-  | ||
|   | | 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_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 record shift (RESHIFT) hardware block used for RAM re-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  | ||
|}  | |||
Returns whether [[#Bitmap|private_key4]] is empty or not.  | |||
=== Cache ===  | |||
{| class="wikitable" border="1"  | |||
!  Name  | |||
!  Address  | |||
|-  | |-  | ||
|   | | FUSE_PRODUCTION_MODE  | ||
|   | | 0x7000F900  | ||
|-  | |-  | ||
|   | | FUSE_JTAG_SECUREID_VALID  | ||
|   | | 0x7000F904  | ||
|-  | |-  | ||
|   | | FUSE_ODM_LOCK  | ||
|   | | 0x7000F908  | ||
|-  | |-  | ||
|   | | FUSE_OPT_OPENGL_EN  | ||
|   | | 0x7000F90C  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_SKU_INFO|FUSE_SKU_INFO]]  | ||
|   | | 0x7000F910  | ||
|-  | |-  | ||
|   | | FUSE_CPU_SPEEDO_0_CALIB  | ||
|   | | 0x7000F914  | ||
|-  | |-  | ||
|   | | FUSE_CPU_IDDQ_CALIB  | ||
|   | | 0x7000F918  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_OPT_FT_REV|FUSE_OPT_FT_REV]]  | ||
|   | | 0x7000F928  | ||
|-  | |-  | ||
|   | | FUSE_CPU_SPEEDO_1_CALIB  | ||
|   | | 0x7000F92C  | ||
|-  | |-  | ||
|   | | FUSE_CPU_SPEEDO_2_CALIB  | ||
|   | | 0x7000F930  | ||
|-  | |-  | ||
|   | | FUSE_SOC_SPEEDO_0_CALIB  | ||
|   | | 0x7000F934  | ||
|-  | |-  | ||
|   | | [[#FUSE_SOC_SPEEDO_1_CALIB|FUSE_SOC_SPEEDO_1_CALIB]]  | ||
|   | | 0x7000F938  | ||
|-  | |-  | ||
|   | | FUSE_SOC_SPEEDO_2_CALIB  | ||
|   | | 0x7000F93C  | ||
|-  | |-  | ||
|   | | FUSE_SOC_IDDQ_CALIB  | ||
|   | | 0x7000F940  | ||
|-  | |-  | ||
|   | | [[#FUSE_FA|FUSE_FA]]  | ||
|   | | 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]]  | ||
|   | | 0x7000F964  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY1]]  | ||
|   | | 0x7000F968  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY2]]  | ||
|   | | 0x7000F96C  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY3]]  | ||
|   | | 0x7000F970  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY4]]  | ||
|   | | 0x7000F974  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY5]]  | ||
|   | | 0x7000F978  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY6]]  | ||
|   | | 0x7000F97C  | ||
|-  | |-  | ||
|   | | [[#FUSE_PUBLIC_KEY|FUSE_PUBLIC_KEY7]]  | ||
|   | | 0x7000F980  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR1_CALIB  | ||
|   | | 0x7000F984  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR2_CALIB  | ||
|   | | 0x7000F988  | ||
|-  | |-  | ||
|   | | [[#FUSE_OPT_CP_REV|FUSE_OPT_CP_REV]]  | ||
|   | | 0x7000F990  | ||
|-  | |-  | ||
|   | | FUSE_OPT_PFG  | ||
|   | | 0x7000F994  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR0_CALIB  | ||
|   | | 0x7000F998  | ||
|-  | |-  | ||
|   | | FUSE_FIRST_BOOTROM_PATCH_SIZE  | ||
|   | | 0x7000F99C  | ||
|-  | |-  | ||
|   | | FUSE_SECURITY_MODE  | ||
|   | | 0x7000F9A0  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY0]]  | ||
|   | | 0x7000F9A4  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY1]]  | ||
|   | | 0x7000F9A8  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY2]]  | ||
|   | | 0x7000F9AC  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY3]]  | ||
|   | | 0x7000F9B0  | ||
|-  | |-  | ||
|   | | [[#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY4]]  | ||
|   | | 0x7000F9B4  | ||
|-  | |-  | ||
|   | | [[#FUSE_ARM_JTAG_DIS|FUSE_ARM_JTAG_DIS]]  | ||
|   | | 0x7000F9B8  | ||
|-  | |-  | ||
|   | | FUSE_BOOT_DEVICE_INFO  | ||
|   | | 0x7000F9BC  | ||
|-  | |-  | ||
| [[#  | | [[#FUSE_RESERVED_SW|FUSE_RESERVED_SW]]  | ||
|   | | 0x7000F9C0  | ||
|-  | |-  | ||
|   | | FUSE_OPT_VP9_DISABLE  | ||
|   | | 0x7000F9C4  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM0|FUSE_RESERVED_ODM0]]  | ||
|   | | 0x7000F9C8  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM1|FUSE_RESERVED_ODM1]]  | ||
|   | | 0x7000F9CC  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM2|FUSE_RESERVED_ODM2]]  | ||
|   | | 0x7000F9D0  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM3|FUSE_RESERVED_ODM3]]  | ||
|   | | 0x7000F9D4  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]  | ||
|   | | 0x7000F9D8  | ||
|-  | |-  | ||
|   | | FUSE_RESERVED_ODM5  | ||
|   | | 0x7000F9DC  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM6|FUSE_RESERVED_ODM6]]  | ||
|   | | 0x7000F9E0  | ||
|-  | |-  | ||
|   | | [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]]  | ||
|   | | 0x7000F9E4  | ||
|-  | |-  | ||
|   | | FUSE_OBS_DIS  | ||
|   | | 0x7000F9E8  | ||
|-  | |-  | ||
|   | | FUSE_USB_CALIB  | ||
|   | | 0x7000F9F0  | ||
|-  | |-  | ||
|   | | [[#FUSE_SKU_DIRECT_CONFIG|FUSE_SKU_DIRECT_CONFIG]]  | ||
|   | | 0x7000F9F4  | ||
|-  | |-  | ||
|   | | FUSE_KFUSE_PRIVKEY_CTRL  | ||
|   | | 0x7000F9F8  | ||
|-  | |-  | ||
|   | | FUSE_PACKAGE_INFO  | ||
|   | | 0x7000F9FC  | ||
|-  | |-  | ||
|   | | FUSE_OPT_VENDOR_CODE  | ||
|   | | 0x7000FA00  | ||
|-  | |-  | ||
|   | | FUSE_OPT_FAB_CODE  | ||
|   | | 0x7000FA04  | ||
|-  | |-  | ||
|   | | FUSE_OPT_LOT_CODE_0  | ||
|   | | 0x7000FA08  | ||
|-  | |-  | ||
|   | | FUSE_OPT_LOT_CODE_1  | ||
|   | | 0x7000FA0C  | ||
|-  | |-  | ||
|   | | FUSE_OPT_WAFER_ID  | ||
|   | | 0x7000FA10  | ||
|-  | |-  | ||
|   | | FUSE_OPT_X_COORDINATE  | ||
|   | | 0x7000FA14  | ||
|-  | |-  | ||
|   | | FUSE_OPT_Y_COORDINATE  | ||
|   | | 0x7000FA18  | ||
|-  | |-  | ||
|   | | [[#FUSE_OPT_SEC_DEBUG_EN|FUSE_OPT_SEC_DEBUG_EN]]  | ||
|   | | 0x7000FA1C  | ||
|-  | |-  | ||
|   | | FUSE_OPT_OPS_RESERVED  | ||
|   | | 0x7000FA20  | ||
|-  | |-  | ||
|   | | FUSE_SATA_CALIB  | ||
|   | | 0x7000FA24  | ||
|-  | |-  | ||
|   | | FUSE_GPU_IDDQ_CALIB  | ||
|   | | 0x7000FA28  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR3_CALIB  | ||
|   | | 0x7000FA2C  | ||
|-  | |-  | ||
|   | | FUSE_CLOCK_BOUNDOUT0  | ||
|   | | 0x7000FA30  | ||
|-  | |-  | ||
|   | | FUSE_CLOCK_BOUNDOUT1  | ||
|   | | 0x7000FA34  | ||
|-  | |-  | ||
|   | | FUSE_OPT_SAMPLE_TYPE  | ||
|   | | 0x7000FA44  | ||
|-  | |-  | ||
|   | | FUSE_OPT_SUBREVISION  | ||
|   | | 0x7000FA48  | ||
|-  | |-  | ||
|   | | FUSE_OPT_SW_RESERVED_0  | ||
|   | | 0x7000FA4C  | ||
|-  | |-  | ||
|   | | FUSE_OPT_SW_RESERVED_1  | ||
|   | | 0x7000FA50  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR4_CALIB  | ||
|   | | 0x7000FA54  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR5_CALIB  | ||
|   | | 0x7000FA58  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR6_CALIB  | ||
|   | | 0x7000FA5C  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR7_CALIB  | ||
|   | | 0x7000FA60  | ||
|-  | |-  | ||
|   | | [[#FUSE_OPT_PRIV_SEC_DIS|FUSE_OPT_PRIV_SEC_DIS]]  | ||
|   | | 0x7000FA64  | ||
|-  | |-  | ||
|   | | [[#FUSE_PKC_DISABLE|FUSE_PKC_DISABLE]]  | ||
|   | | 0x7000FA68  | ||
|-  | |-  | ||
|   | | FUSE_FUSE2TSEC_DEBUG_DISABLE  | ||
|   | | 0x7000FA7C  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR_COMMON  | ||
|   | | 0x7000FA80  | ||
|-  | |-  | ||
|   | | 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  | ||
|-  | |-  | ||
|   | | 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  | ||
|-  | |-  | ||
|   | | FUSE_VMIN_CALIBRATION  | ||
|   | | 0x7000FADC  | ||
|-  | |-  | ||
|   | | FUSE_AGING_SENSOR_CALIBRATION  | ||
|   | | 0x7000FAE0  | ||
|-  | |-  | ||
|   | | FUSE_DEBUG_AUTHENTICATION  | ||
|   | | 0x7000FAE4  | ||
|-  | |-  | ||
|   | | FUSE_SECURE_PROVISION_INDEX  | ||
|   | | 0x7000FAE8  | ||
|-  | |-  | ||
|   | | FUSE_SECURE_PROVISION_INFO  | ||
|   | | 0x7000FAEC  | ||
|-  | |-  | ||
|   | | FUSE_OPT_GPU_DISABLE_CP1  | ||
|   | | 0x7000FAF0  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_ENDIS  | ||
|   | | 0x7000FAF4  | ||
|-  | |-  | ||
|   | | [[#FUSE_ECO_RESERVE_0|FUSE_ECO_RESERVE_0]]  | ||
|   | | 0x7000FAF8  | ||
|-  | |-  | ||
|   | | FUSE_RESERVED_CALIB0  | ||
|   | | 0x7000FB04  | ||
|-  | |-  | ||
|   | | FUSE_RESERVED_CALIB1  | ||
|   | | 0x7000FB08  | ||
|-  | |-  | ||
|   | | FUSE_OPT_GPU_TPC0_DISABLE  | ||
|   | | 0x7000FB0C  | ||
|-  | |-  | ||
|   | | FUSE_OPT_GPU_TPC0_DISABLE_CP1  | ||
|   | | 0x7000FB10  | ||
|-  | |-  | ||
|   | | FUSE_OPT_CPU_DISABLE  | ||
|   | | 0x7000FB14  | ||
|-  | |-  | ||
|   | | FUSE_OPT_CPU_DISABLE_CP1  | ||
|   | | 0x7000FB18  | ||
|-  | |-  | ||
|   | | FUSE_TSENSOR10_CALIB  | ||
|   | | 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  | ||
|   | | 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  | ||
|   | | 0x7000FB50  | ||
|-  | |-  | ||
|   | | FUSE_RESERVED_FIELD  | ||
|   | | 0x7000FB54  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_REALIGNMENT_REG  | ||
| 0x7000FB7C  | |||
|   | |||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_0  | ||
|   | | 0x7000FB80  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_1  | ||
|   | | 0x7000FB84  | ||
|-  | |-  | ||
|   | | [[#FUSE_SPARE_BIT_2|FUSE_SPARE_BIT_2]]  | ||
|   | | 0x7000FB88  | ||
|-  | |-  | ||
|   | | [[#FUSE_SPARE_BIT_3|FUSE_SPARE_BIT_3]]  | ||
|   | | 0x7000FB8C  | ||
|-  | |-  | ||
|   | | [[#FUSE_SPARE_BIT_4|FUSE_SPARE_BIT_4]]  | ||
|   | | 0x7000FB90  | ||
|  | |||
|-  | |-  | ||
|   | | [[#FUSE_SPARE_BIT_5|FUSE_SPARE_BIT_5]]  | ||
|   | | 0x7000FB94  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_6  | ||
|   | | 0x7000FB98  | ||
|-  | |||
| FUSE_SPARE_BIT_7  | |||
| 0x7000FB9C  | |||
|-  | |||
| FUSE_SPARE_BIT_8  | |||
| 0x7000FBA0  | |||
|-  | |||
| FUSE_SPARE_BIT_9  | |||
| 0x7000FBA4  | |||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_10  | ||
|   | | 0x7000FBA8  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_11  | ||
|   | | 0x7000FBAC  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_12  | ||
|   | | 0x7000FBB0  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_13  | ||
|   | | 0x7000FBB4  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_14  | ||
|   | | 0x7000FBB8  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_15  | ||
|   | | 0x7000FBBC  | ||
|-  | |-  | ||
|   | | FUSE_SPARE_BIT_16  | ||
|   | | 0x7000FBC0  | ||
|-  | |-  | ||
|   | | 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  | |||
|-  | |||
| FUSE_SPARE_BIT_30  | |||
| 0x7000FBF8  | |||
|-  | |||
| FUSE_SPARE_BIT_31  | |||
| 0x7000FBFC  | |||
|}  | |||
===   | ==== FUSE_SKU_INFO ====  | ||
Stores the SKU ID (must be 0x83).  | |||
===   | ==== FUSE_OPT_FT_REV ====  | ||
Stores the FT (Final Test) revision.  | |||
The   | Original Erista units have this value set to 0xA0 (revision 5.0). The first batch of patched Erista  units have this value set to 0xC0 (revision 6.0). The second batch of patched Erista units have this value set to 0xE0 (revision 7.0).  | ||
Mariko and Lite units have this value set to 0x60 (revision 3.0). OLED units have this value set to 0x81 (revision 4.1).  | |||
==== FUSE_SOC_SPEEDO_1_CALIB ====  | |||
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 Erista units have this value set to 0xA0 (revision 5.0). Patched Erista units have this value set to 0x103 (revision 8.3).  | |||
Mariko units have this value set to 0x40 (revision 2.0). Lite units have this value set to 0x41 (revision 2.1). OLED units have this value set to 0x100 (revision 8.0).  | |||
==== FUSE_PRIVATE_KEY ====  | |||
Stores the 160-bit private key (128 bit SBK + 32-bit device key).  | |||
Reads to these registers after [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]] is set produce all-FF output.  | |||
==== FUSE_ARM_JTAG_DIS ====  | |||
Controls access to the Arm JTAG interface.  | |||
Production Erista and Mariko units have this value set to 0x1, while development Erista and Mariko units do not.  | |||
==== FUSE_RESERVED_SW ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-2  | |||
| Boot device  | |||
|-  | |||
| 3  | |||
| Skip device selection straps  | |||
|-  | |||
| 4  | |||
| Enable charger detection  | |||
|-  | |||
| 5  | |||
| Enable watchdog  | |||
|-  | |||
| 6  | |||
| Forced RCM two button mode (0 = VOLUME_UP, 1 = VOLUME_UP + HOME)  | |||
|-  | |||
| 7  | |||
| RCM USB controller mode (0 = USB 2.0, 1 = XUSB)  | |||
|}  | |||
Stores software reserved configuration values.  | |||
Production Erista and Mariko units have the forced RCM two button mode set, while development Erista and Mariko units do not.  | |||
Original Erista units have the RCM USB controller mode set to USB 2.0, while the first batch of patched Erista units have the RCM USB controller mode set to XUSB. Mariko ignores this and uses XUSB regardless for RCM.  | |||
==== FUSE_RESERVED_ODM0 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| OdmTestId0  | |||
|}  | |||
==== FUSE_RESERVED_ODM1 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| OdmTestId1  | |||
|}  | |||
==== FUSE_RESERVED_ODM2 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| OdmTestId2  | |||
|}  | |||
[5.0.0+] If [[#FUSE_RESERVED_ODM4|FormatVersion]] is 1, this becomes:   | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-4  | |||
| DeviceUniqueKeyGeneration  | |||
|-  | |||
| 5-31  | |||
| Reserved  | |||
|}  | |||
==== FUSE_RESERVED_ODM3 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| OdmTestId3  | |||
|}  | |||
[5.0.0+] If [[#FUSE_RESERVED_ODM4|FormatVersion]] is 1, this becomes:    | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| Reserved  | |||
|}  | |||
==== FUSE_RESERVED_ODM4 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-1  | |||
| HardwareState1  | |||
|-  | |||
| 2  | |||
| HardwareType1  | |||
|-  | |||
| [1.0.0-3.0.2] 3-5  | |||
[4.0.0+] 3-7  | |||
| [15.0.0+] DramId1 ([4.0.0-14.1.2] DramId)  | |||
|-  | |||
| 8  | |||
| HardwareType2  | |||
|-  | |||
| 9  | |||
| HardwareState2  | |||
|-  | |||
| 10  | |||
| [3.0.0+] QuestState  | |||
|-  | |||
| 11  | |||
| [5.0.0+] FormatVersion  | |||
|-  | |||
| 12-14  | |||
| [15.0.0+] DramId2  | |||
|-  | |||
| 16-19  | |||
| [4.0.0+] HardwareType3  | |||
|}  | |||
Stores device configuration parameters.  | |||
==== FUSE_RESERVED_ODM5 ====  | |||
Empty and unused.  | |||
==== 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_SKU_DIRECT_CONFIG ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0  | |||
| Disable SCPU  | |||
|-  | |||
| 1  | |||
| Disable FCPU0  | |||
|-  | |||
| 2  | |||
| Disable FCPU1  | |||
|-  | |||
| 3  | |||
| Disable FCPU2  | |||
|-  | |||
| 4  | |||
| Disable FCPU3  | |||
|-  | |||
| 5  | |||
| Disable all CPUs  | |||
|}  | |||
Controls which CPUs can be used.  | |||
Erista units have this value set to 0x00 (both Cortex-A53 and Cortex-A57 clusters are usable).  | |||
Mariko units have this value set to 0x01 (only the Cortex-A57 cluster is usable).  | |||
==== FUSE_OPT_SEC_DEBUG_EN ====  | |||
Controls the [[TSEC#TSEC_SCP_CTL_STAT|Falcon SCP]] debug mode.  | |||
==== FUSE_OPT_PRIV_SEC_DIS ====  | |||
Controls the [[TSEC#FALCON_SCTL|Falcon Light Secure]] feature.  | |||
==== FUSE_PKC_DISABLE ====  | |||
Returns if public key crypto is used or not.  | |||
==== FUSE_ODM_INFO ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-7  | |||
| Reserved  | |||
|-  | |||
| 8  | |||
| Disable DBGEN  | |||
|-  | |||
| 9  | |||
| Disable NIDEN  | |||
|-  | |||
| 10  | |||
| Disable SPIDEN  | |||
|-  | |||
| 11  | |||
| Disable SPNIDEN  | |||
|-  | |||
| 12  | |||
| Disable DEVICEEN  | |||
|}  | |||
Production Erista and Mariko units have this value set to 0x1F00 (all signals disabled).  | |||
Development Erista and Mariko units have this value set to 0x0000 (all signals enabled).  | |||
==== FUSE_ECO_RESERVE_0 ====  | |||
Returns the chip unique AID.  | |||
==== FUSE_SPARE_BIT_2 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0  | |||
| Speedo fusing revision  | |||
|}  | |||
==== FUSE_SPARE_BIT_3 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0  | |||
| Speedo fusing revision  | |||
|}  | |||
==== FUSE_SPARE_BIT_4 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0  | |||
| Speedo fusing revision  | |||
|}  | |||
==== FUSE_SPARE_BIT_5 ====  | |||
Must be non-zero on production 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 production 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 ===  | |||
{| class="wikitable" border="1"  | |||
!  Name  | |||
!  Address  | |||
|-  | |||
| [[#FUSE_FUSECTRL|FUSE_FUSECTRL]]  | |||
| 0x7000F800  | |||
|-  | |||
| [[#FUSE_FUSEADDR|FUSE_FUSEADDR]]  | |||
| 0x7000F804  | |||
|-  | |||
| [[#FUSE_FUSERDATA|FUSE_FUSERDATA]]  | |||
| 0x7000F808  | |||
|-  | |||
| [[#FUSE_FUSEWDATA|FUSE_FUSEWDATA]]  | |||
| 0x7000F80C  | |||
|-  | |||
| [[#FUSE_FUSETIME_RD1|FUSE_FUSETIME_RD1]]  | |||
| 0x7000F810  | |||
|-  | |||
| [[#FUSE_FUSETIME_RD2|FUSE_FUSETIME_RD2]]  | |||
| 0x7000F814  | |||
|-  | |||
| [[#FUSE_FUSETIME_PGM1|FUSE_FUSETIME_PGM1]]  | |||
| 0x7000F818  | |||
|-  | |||
| [[#FUSE_FUSETIME_PGM2|FUSE_FUSETIME_PGM2]]  | |||
| 0x7000F81C  | |||
|-  | |||
| [[#FUSE_PRIV2INTFC_START|FUSE_PRIV2INTFC_START]]  | |||
| 0x7000F820  | |||
|-  | |||
| [[#FUSE_FUSEBYPASS|FUSE_FUSEBYPASS]]  | |||
| 0x7000F824  | |||
|-  | |||
| [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]]  | |||
| 0x7000F828  | |||
|-  | |||
| [[#FUSE_DISABLEREGPROGRAM|FUSE_DISABLEREGPROGRAM]]  | |||
| 0x7000F82C  | |||
|-  | |||
| [[#FUSE_WRITE_ACCESS_SW|FUSE_WRITE_ACCESS_SW]]  | |||
| 0x7000F830  | |||
|-  | |||
| [[#FUSE_PRIV2RESHIFT|FUSE_PRIV2RESHIFT]]  | |||
| 0x7000F83C  | |||
|-  | |||
| [[#FUSE_FUSETIME_RD3|FUSE_FUSETIME_RD3]]  | |||
| 0x7000F84C  | |||
|-  | |||
| [[#FUSE_SPARE_ADDR_START|FUSE_SPARE_ADDR_START]]  | |||
| 0x7000F860  | |||
|-  | |||
| [[#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_SPARE_ADDR_START ====  | ||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-31  | |||
| FUSE_SPARE_ADDR_START_DATA  | |||
|}  | |||
Returns the offset of the spare bit fuse registers (always 0x380).  | |||
=== Cache ===  | |||
{| class="wikitable" border="1"  | |||
!  Name  | |||
!  Address  | |||
|-  | |||
| FUSE_RESERVED_ODM8  | |||
| 0x7000F898  | |||
|-  | |||
| FUSE_RESERVED_ODM9  | |||
| 0x7000F89C  | |||
|-  | |||
| FUSE_RESERVED_ODM10  | |||
| 0x7000F8A0  | |||
|-  | |||
| FUSE_RESERVED_ODM11  | |||
| 0x7000F8A4  | |||
|-  | |||
| FUSE_RESERVED_ODM12  | |||
| 0x7000F8A8  | |||
|-  | |||
| FUSE_RESERVED_ODM13  | |||
| 0x7000F8AC  | |||
|-  | |||
| FUSE_RESERVED_ODM14  | |||
| 0x7000F8B0  | |||
|-  | |||
| FUSE_RESERVED_ODM15  | |||
| 0x7000F8B4  | |||
|-  | |||
| FUSE_RESERVED_ODM16  | |||
| 0x7000F8B8  | |||
|-  | |||
| FUSE_RESERVED_ODM17  | |||
| 0x7000F8BC  | |||
|-  | |||
| FUSE_RESERVED_ODM18  | |||
| 0x7000F8C0  | |||
|-  | |||
| FUSE_RESERVED_ODM19  | |||
| 0x7000F8C4  | |||
|-  | |||
| FUSE_RESERVED_ODM20  | |||
| 0x7000F8C8  | |||
|-  | |||
| FUSE_RESERVED_ODM21  | |||
| 0x7000F8CC  | |||
|-  | |||
| [[#FUSE_KEK|FUSE_KEK00]]  | |||
| 0x7000F8D0  | |||
|-  | |||
| [[#FUSE_KEK|FUSE_KEK01]]  | |||
| 0x7000F8D4  | |||
|-  | |||
| [[#FUSE_KEK|FUSE_KEK02]]  | |||
| 0x7000F8D8  | |||
|-  | |||
| [[#FUSE_KEK|FUSE_KEK03]]  | |||
| 0x7000F8DC  | |||
|-  | |||
| [[#FUSE_BEK|FUSE_BEK00]]  | |||
| 0x7000F8E0  | |||
|-  | |||
| [[#FUSE_BEK|FUSE_BEK01]]  | |||
| 0x7000F8E4  | |||
|-  | |||
| [[#FUSE_BEK|FUSE_BEK02]]  | |||
| 0x7000F8E8  | |||
|-  | |||
| [[#FUSE_BEK|FUSE_BEK03]]  | |||
| 0x7000F8EC  | |||
|-  | |||
| FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT  | |||
| 0x7000F8F0  | |||
|-  | |||
| FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT  | |||
| 0x7000F8F4  | |||
|-  | |||
| FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT  | |||
| 0x7000F8F8  | |||
|-  | |||
| FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT  | |||
| 0x7000F8FC  | |||
|-  | |||
| FUSE_PRODUCTION_MODE  | |||
| 0x7000F900  | |||
|-  | |||
| FUSE_JTAG_SECUREID_VALID  | |||
| 0x7000F904  | |||
|-  | |||
| FUSE_ODM_LOCK  | |||
| 0x7000F908  | |||
|-  | |||
| FUSE_OPT_OPENGL_EN  | |||
| 0x7000F90C  | |||
|-  | |||
| FUSE_SKU_INFO  | |||
| 0x7000F910  | |||
|-  | |||
| FUSE_CPU_SPEEDO_0_CALIB  | |||
| 0x7000F914  | |||
|-  | |||
| FUSE_CPU_IDDQ_CALIB  | |||
| 0x7000F918  | |||
|-  | |||
| FUSE_RESERVED_ODM22  | |||
| 0x7000F91C  | |||
|-  | |||
| FUSE_RESERVED_ODM23  | |||
| 0x7000F920  | |||
|-  | |||
| FUSE_RESERVED_ODM24  | |||
| 0x7000F924  | |||
|-  | |||
| FUSE_OPT_FT_REV  | |||
| 0x7000F928  | |||
|-  | |||
| FUSE_CPU_SPEEDO_1_CALIB  | |||
| 0x7000F92C  | |||
|-  | |||
| FUSE_CPU_SPEEDO_2_CALIB  | |||
| 0x7000F930  | |||
|-  | |||
| FUSE_SOC_SPEEDO_0_CALIB  | |||
| 0x7000F934  | |||
|-  | |||
| FUSE_SOC_SPEEDO_1_CALIB  | |||
| 0x7000F938  | |||
|-  | |||
| FUSE_SOC_SPEEDO_2_CALIB  | |||
| 0x7000F93C  | |||
|-  | |||
| FUSE_SOC_IDDQ_CALIB  | |||
| 0x7000F940  | |||
|-  | |||
| FUSE_RESERVED_ODM25  | |||
| 0x7000F944  | |||
|-  | |||
| FUSE_FA  | |||
| 0x7000F948  | |||
|-  | |||
| [[#FUSE_RESERVED_PRODUCTION|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_KEY0  | |||
| 0x7000F964  | |||
|-  | |||
| FUSE_PUBLIC_KEY1  | |||
| 0x7000F968  | |||
|-  | |||
| FUSE_PUBLIC_KEY2  | |||
| 0x7000F96C  | |||
|-  | |||
| FUSE_PUBLIC_KEY3  | |||
| 0x7000F970  | |||
|-  | |||
| FUSE_PUBLIC_KEY4  | |||
| 0x7000F974  | |||
|-  | |||
| FUSE_PUBLIC_KEY5  | |||
| 0x7000F978  | |||
|-  | |||
| FUSE_PUBLIC_KEY6  | |||
| 0x7000F97C  | |||
|-  | |||
| FUSE_PUBLIC_KEY7  | |||
| 0x7000F980  | |||
|-  | |||
| FUSE_TSENSOR1_CALIB  | |||
| 0x7000F984  | |||
|-  | |||
| FUSE_TSENSOR2_CALIB  | |||
| 0x7000F988  | |||
|-  | |||
| FUSE_OPT_SECURE_SCC_DIS  | |||
| 0x7000F98C  | |||
|-  | |||
The first bootloader verifies [[#FUSE_RESERVED_ODM7|FUSE_RESERVED_ODM7]] to prevent downgrading.  | | FUSE_OPT_CP_REV  | ||
| 0x7000F990  | |||
|-  | |||
| FUSE_OPT_PFG  | |||
| 0x7000F994  | |||
|-  | |||
| FUSE_TSENSOR0_CALIB  | |||
| 0x7000F998  | |||
|-  | |||
| FUSE_FIRST_BOOTROM_PATCH_SIZE  | |||
| 0x7000F99C  | |||
|-  | |||
| FUSE_SECURITY_MODE  | |||
| 0x7000F9A0  | |||
|-  | |||
| FUSE_PRIVATE_KEY0  | |||
| 0x7000F9A4  | |||
|-  | |||
| FUSE_PRIVATE_KEY1  | |||
| 0x7000F9A8  | |||
|-  | |||
| FUSE_PRIVATE_KEY2  | |||
| 0x7000F9AC  | |||
|-  | |||
| FUSE_PRIVATE_KEY3  | |||
| 0x7000F9B0  | |||
|-  | |||
| FUSE_PRIVATE_KEY4  | |||
| 0x7000F9B4  | |||
|-  | |||
| FUSE_ARM_JTAG_DIS  | |||
| 0x7000F9B8  | |||
|-  | |||
| FUSE_BOOT_DEVICE_INFO  | |||
| 0x7000F9BC  | |||
|-  | |||
| FUSE_RESERVED_SW  | |||
| 0x7000F9C0  | |||
|-  | |||
| FUSE_OPT_VP9_DISABLE  | |||
| 0x7000F9C4  | |||
|-  | |||
| FUSE_RESERVED_ODM0  | |||
| 0x7000F9C8  | |||
|-  | |||
| FUSE_RESERVED_ODM1  | |||
| 0x7000F9CC  | |||
|-  | |||
| FUSE_RESERVED_ODM2  | |||
| 0x7000F9D0  | |||
|-  | |||
| FUSE_RESERVED_ODM3  | |||
| 0x7000F9D4  | |||
|-  | |||
| FUSE_RESERVED_ODM4  | |||
| 0x7000F9D8  | |||
|-  | |||
| FUSE_RESERVED_ODM5  | |||
| 0x7000F9DC  | |||
|-  | |||
| FUSE_RESERVED_ODM6  | |||
| 0x7000F9E0  | |||
|-  | |||
| FUSE_RESERVED_ODM7  | |||
| 0x7000F9E4  | |||
|-  | |||
| FUSE_OBS_DIS  | |||
| 0x7000F9E8  | |||
|-  | |||
| [[#FUSE_OPT_NVJTAG_PROTECTION_ENABLE|FUSE_OPT_NVJTAG_PROTECTION_ENABLE]]  | |||
| 0x7000F9EC  | |||
|-  | |||
| FUSE_USB_CALIB  | |||
| 0x7000F9F0  | |||
|-  | |||
| FUSE_SKU_DIRECT_CONFIG  | |||
| 0x7000F9F4  | |||
|-  | |||
| FUSE_KFUSE_PRIVKEY_CTRL  | |||
| 0x7000F9F8  | |||
|-  | |||
| FUSE_PACKAGE_INFO  | |||
| 0x7000F9FC  | |||
|-  | |||
| FUSE_OPT_VENDOR_CODE  | |||
| 0x7000FA00  | |||
|-  | |||
| FUSE_OPT_FAB_CODE  | |||
| 0x7000FA04  | |||
|-  | |||
| FUSE_OPT_LOT_CODE_0  | |||
| 0x7000FA08  | |||
|-  | |||
| FUSE_OPT_LOT_CODE_1  | |||
| 0x7000FA0C  | |||
|-  | |||
| FUSE_OPT_WAFER_ID  | |||
| 0x7000FA10  | |||
|-  | |||
| FUSE_OPT_X_COORDINATE  | |||
| 0x7000FA14  | |||
|-  | |||
| FUSE_OPT_Y_COORDINATE  | |||
| 0x7000FA18  | |||
|-  | |||
| FUSE_OPT_SEC_DEBUG_EN  | |||
| 0x7000FA1C  | |||
|-  | |||
| FUSE_OPT_OPS_RESERVED  | |||
| 0x7000FA20  | |||
|-  | |||
|   | |||
| 0x7000FA24  | |||
|-  | |||
| FUSE_GPU_IDDQ_CALIB  | |||
| 0x7000FA28  | |||
|-  | |||
| FUSE_TSENSOR3_CALIB  | |||
| 0x7000FA2C  | |||
|-  | |||
| FUSE_CLOCK_BONDOUT0  | |||
| 0x7000FA30  | |||
|-  | |||
| FUSE_CLOCK_BONDOUT1  | |||
| 0x7000FA34  | |||
|-  | |||
| FUSE_RESERVED_ODM26  | |||
| 0x7000FA38  | |||
|-  | |||
| FUSE_RESERVED_ODM27  | |||
| 0x7000FA3C  | |||
|-  | |||
| [[#FUSE_RESERVED_ODM28|FUSE_RESERVED_ODM28]]  | |||
| 0x7000FA40  | |||
|-  | |||
| FUSE_OPT_SAMPLE_TYPE  | |||
| 0x7000FA44  | |||
|-  | |||
| FUSE_OPT_SUBREVISION  | |||
| 0x7000FA48  | |||
|-  | |||
| FUSE_OPT_SW_RESERVED_0  | |||
| 0x7000FA4C  | |||
|-  | |||
| FUSE_OPT_SW_RESERVED_1  | |||
| 0x7000FA50  | |||
|-  | |||
| FUSE_TSENSOR4_CALIB  | |||
| 0x7000FA54  | |||
|-  | |||
| FUSE_TSENSOR5_CALIB  | |||
| 0x7000FA58  | |||
|-  | |||
| FUSE_TSENSOR6_CALIB  | |||
| 0x7000FA5C  | |||
|-  | |||
| FUSE_TSENSOR7_CALIB  | |||
| 0x7000FA60  | |||
|-  | |||
| FUSE_OPT_PRIV_SEC_DIS  | |||
| 0x7000FA64  | |||
|-  | |||
| [[#FUSE_BOOT_SECURITY_INFO|FUSE_BOOT_SECURITY_INFO]]  | |||
| 0x7000FA68  | |||
|-  | |||
| FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT  | |||
| 0x7000FA6C  | |||
|-  | |||
| FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT  | |||
| 0x7000FA70  | |||
|-  | |||
| FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT  | |||
| 0x7000FA74  | |||
|-  | |||
| FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT  | |||
| 0x7000FA78  | |||
|-  | |||
| FUSE_FUSE2TSEC_DEBUG_DISABLE  | |||
| 0x7000FA7C  | |||
|-  | |||
| FUSE_TSENSOR_COMMON  | |||
| 0x7000FA80  | |||
|-  | |||
| FUSE_OPT_CP_BIN  | |||
| 0x7000FA84  | |||
|-  | |||
| FUSE_OPT_GPU_DISABLE  | |||
| 0x7000FA88  | |||
|-  | |||
| FUSE_OPT_FT_BIN  | |||
| 0x7000FA8C  | |||
|-  | |||
| FUSE_OPT_DONE_MAP  | |||
| 0x7000FA90  | |||
|-  | |||
| FUSE_RESERVED_ODM29  | |||
| 0x7000FA94  | |||
|-  | |||
| FUSE_APB2JTAG_DISABLE  | |||
| 0x7000FA98  | |||
|-  | |||
| FUSE_ODM_INFO  | |||
| 0x7000FA9C  | |||
|-  | |||
| FUSE_ARM_CRYPT_DE_FEATURE  | |||
| 0x7000FAA8  | |||
|-  | |||
| FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT  | |||
| 0x7000FAB0  | |||
|-  | |||
| FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT  | |||
| 0x7000FAB4  | |||
|-  | |||
| FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT  | |||
| 0x7000FAB8  | |||
|-  | |||
| FUSE_OPT_RAM_KP_TSMCDP_PO4SVT  | |||
| 0x7000FABC  | |||
|-  | |||
| 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  | |||
|-  | |||
| FUSE_VMIN_CALIBRATION  | |||
| 0x7000FADC  | |||
|-  | |||
| FUSE_AGING_SENSOR_CALIBRATION  | |||
| 0x7000FAE0  | |||
|-  | |||
| FUSE_DEBUG_AUTHENTICATION  | |||
| 0x7000FAE4  | |||
|-  | |||
| FUSE_SECURE_PROVISION_INDEX  | |||
| 0x7000FAE8  | |||
|-  | |||
| FUSE_SECURE_PROVISION_INFO  | |||
| 0x7000FAEC  | |||
|-  | |||
| FUSE_OPT_GPU_DISABLE_CP1  | |||
| 0x7000FAF0  | |||
|-  | |||
| FUSE_SPARE_ENDIS  | |||
| 0x7000FAF4  | |||
|-  | |||
| FUSE_ECO_RESERVE_0  | |||
| 0x7000FAF8  | |||
|-  | |||
| FUSE_RESERVED_CALIB0  | |||
| 0x7000FB04  | |||
|-  | |||
| FUSE_RESERVED_CALIB1  | |||
| 0x7000FB08  | |||
|-  | |||
| FUSE_OPT_GPU_TPC0_DISABLE  | |||
| 0x7000FB0C  | |||
|-  | |||
| FUSE_OPT_GPU_TPC0_DISABLE_CP1  | |||
| 0x7000FB10  | |||
|-  | |||
| FUSE_OPT_CPU_DISABLE  | |||
| 0x7000FB14  | |||
|-  | |||
| FUSE_OPT_CPU_DISABLE_CP1  | |||
| 0x7000FB18  | |||
|-  | |||
| FUSE_TSENSOR10_CALIB  | |||
| 0x7000FB1C  | |||
|-  | |||
| FUSE_TSENSOR10_CALIB_AUX  | |||
| 0x7000FB20  | |||
|-  | |||
| FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT  | |||
| 0x7000FB24  | |||
|-  | |||
| FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT  | |||
| 0x7000FB28  | |||
|-  | |||
| FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT  | |||
| 0x7000FB2C  | |||
|-  | |||
| FUSE_OPT_RAM_KP_TSMCDP_PO4HVT  | |||
| 0x7000FB30  | |||
|-  | |||
|   | |||
| 0x7000FB34  | |||
|-  | |||
| FUSE_OPT_GPU_TPC0_DISABLE_CP2  | |||
| 0x7000FB38  | |||
|-  | |||
| FUSE_OPT_GPU_TPC1_DISABLE  | |||
| 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  | |||
| 0x7000FB50  | |||
|-  | |||
| FUSE_RESERVED_FIELD  | |||
| 0x7000FB54  | |||
|-  | |||
| FUSE_SPARE_REALIGNMENT_REG  | |||
| 0x7000FB7C  | |||
|-  | |||
| FUSE_SPARE_BIT_0  | |||
| 0x7000FB80  | |||
|-  | |||
| FUSE_SPARE_BIT_1  | |||
| 0x7000FB84  | |||
|-  | |||
| FUSE_SPARE_BIT_2  | |||
| 0x7000FB88  | |||
|-  | |||
| FUSE_SPARE_BIT_3  | |||
| 0x7000FB8C  | |||
|-  | |||
| FUSE_SPARE_BIT_4  | |||
| 0x7000FB90  | |||
|-  | |||
| FUSE_SPARE_BIT_5  | |||
| 0x7000FB94  | |||
|-  | |||
| FUSE_SPARE_BIT_6  | |||
| 0x7000FB98  | |||
|-  | |||
| FUSE_SPARE_BIT_7  | |||
| 0x7000FB9C  | |||
|-  | |||
| FUSE_SPARE_BIT_8  | |||
| 0x7000FBA0  | |||
|-  | |||
| FUSE_SPARE_BIT_9  | |||
| 0x7000FBA4  | |||
|-  | |||
| FUSE_SPARE_BIT_10  | |||
| 0x7000FBA8  | |||
|-  | |||
| FUSE_SPARE_BIT_11  | |||
| 0x7000FBAC  | |||
|-  | |||
| FUSE_SPARE_BIT_12  | |||
| 0x7000FBB0  | |||
|-  | |||
| FUSE_SPARE_BIT_13  | |||
| 0x7000FBB4  | |||
|-  | |||
| FUSE_SPARE_BIT_14  | |||
| 0x7000FBB8  | |||
|-  | |||
| FUSE_SPARE_BIT_15  | |||
| 0x7000FBBC  | |||
|-  | |||
| FUSE_SPARE_BIT_16  | |||
| 0x7000FBC0  | |||
|-  | |||
| 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  | |||
|}  | |||
==== FUSE_KEK ====  | |||
Stores the 128-bit KEK (Key Encryption Key) encrypted with the FEK (Fuse Encryption Key) selected by [[#FUSE_RESERVED_PRODUCTION|FUSE_RESERVED_PRODUCTION]] and [[#FUSE_BOOT_SECURITY_INFO|FUSE_BOOT_SECURITY_INFO]].  | |||
Reads to these registers after [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]] is set produce all-FF output.  | |||
==== FUSE_BEK ====  | |||
Stores the 128-bit BEK (Boot Encryption Key) encrypted with the FEK (Fuse Encryption Key) selected by [[#FUSE_RESERVED_PRODUCTION|FUSE_RESERVED_PRODUCTION]] and [[#FUSE_BOOT_SECURITY_INFO|FUSE_BOOT_SECURITY_INFO]].  | |||
Reads to these registers after [[#FUSE_PRIVATEKEYDISABLE|FUSE_PRIVATEKEYDISABLE]] is set produce all-FF output.  | |||
==== FUSE_RESERVED_PRODUCTION ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-1  | |||
| Reserved  | |||
|-  | |||
| 2  | |||
| FEK bank select  | |||
|}  | |||
==== FUSE_OPT_NVJTAG_PROTECTION_ENABLE ====  | |||
Controls the NVJTAG protection feature. If enabled, this will permanently disable access to all DFT (Design for Test) functions which include the ability put the chip in FA (Failure Analysis) mode.   | |||
==== FUSE_RESERVED_ODM28 ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0  | |||
| RegulatorType  | |||
|}  | |||
==== FUSE_BOOT_SECURITY_INFO ====  | |||
{| class="wikitable" border="1"  | |||
!  Bits  | |||
!  Description  | |||
|-  | |||
| 0-1  | |||
| Authentication (0 = AES_CMAC, 1 = PKC_RSA)  | |||
|-  | |||
| 2  | |||
| Encryption (0 = DISABLE, 1 = ENABLE)  | |||
|-  | |||
| 3  | |||
| Fuse encryption (0 = DISABLE, 1 = ENABLE)  | |||
|-  | |||
| 4-6  | |||
| Fuse encryption select (0 = TEST_KEY, 1 = NVIDIA_KEY, 2 to 7 = OEM_KEY_0 to OEM_KEY_5)  | |||
|-  | |||
| 7  | |||
| SE atomic context save (0 = DISABLE, 1 = ENABLE)  | |||
|}  | |||
Stores configuration values for the new boot security mechanism.  | |||
Mariko units have authentication set to PKC_RSA, encryption enabled, fuse encryption enabled and fuse encryption select set to OEM_KEY_0 (development units) or OEM_KEY_1 (production units).  | |||
= 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, spare bits and all fuses afterwards in the fuse bitmap, no longer have a redundant alias.  | |||
== Erista ==  | |||
{| 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-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_records  | |||
| 106  | |||
| None  | |||
| 0-192  | |||
|-  | |||
| [[#irom_patch|irom_patch]]  | |||
| 112  | |||
| None  | |||
| 0-2560  | |||
|}  | |||
=== 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 sets APBDEV_PMC_SCRATCH190_0 to 0x01, which LP0 resume code expects.  | |||
<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 8 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 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 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 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_records  | |||
| 170  | |||
| None  | |||
| 0-192  | |||
|-  | |||
| [[#irom_patch_2|irom_patch]]  | |||
| 176  | |||
| None  | |||
| 0-2560  | |||
|}  | |||
=== 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 : svc #0x5b (offset 0xfe)  | |||
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                                  ;  8: 0x62e3ef5b 0x0010c5c6 0x0000ef5b : svc #0x5b (offset 0xfe)  | |||
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>  | |||
==== IROM patch 1 ====  | |||
This patch stubs the function responsible for disabling read access for the SE AES keyslots.  | |||
Due to a programming mistake, when loading the OEM AES keys the aforementioned function would be called with the wrong arguments. The patch prevents this by simply stubbing the function altogether, which is only acceptable because the Mariko's SE hardware already boots with keyslot reading permanently disabled.  | |||
==== IROM patch 2 ====  | |||
This patch forces the function responsible for checking if SE context atomic save is enabled (by checking a fuse) to always return true.  | |||
Some Mariko units have been found to not have the relevant fuse bit (bit 7 in [[#FUSE_BOOT_SECURITY_INFO|FUSE_BOOT_SECURITY_INFO]]) burned, so the patch serves as a workaround for this.  | |||
==== IROM patch 3 ====  | |||
This patch forces a jump to the same routine used by [[#IROM_patch_0_2|IROM patch 0]] if loading a bootloader failed.  | |||
By setting all IRAM memory from 0x4000FC20 to 0x40040000 to 0xEAFFFFFE, a bootloader that somehow failed validation is effectively erased from memory.  | |||
==== IROM patch 4 ====  | |||
This patch stores a stack cookie (value 0x5A55F0E1) after a RCM message is received and before it's validated.  | |||
==== IROM patch 5 ====  | |||
This patch checks the stack cookie stored by [[#IROM_patch_4_2|IROM patch 4]] right after a RCM message is validated.  | |||
If the stack cookie's value is still 0x5A55F0E1, the bootrom jumps to a panic. If it changed to anything other than 0, the same routine used by [[#IROM_patch_0_2|IROM patch 0]] is called. Presumably, this is an attempt at mitigating fault injection attacks against skipping the validation of RCM messages.  | |||
==== IROM patch 6 ====  | |||
This patch sanitizes the crypto context right before receiving a RCM message.  | |||
<syntaxhighlight lang="c">  | |||
 u32 FUSE_PRIVATEKEYDISABLE = 0x7000F828;  | |||
 u32 SE1_CRYPTO_KEYTABLE_ADDR = 0x7001231C;  | |||
 u32 SE2_CRYPTO_KEYTABLE_ADDR = 0x7041231C;  | |||
 u32 SE1_CRYPTO_KEYTABLE_DATA = 0x70012320;  | |||
 u32 SE2_CRYPTO_KEYTABLE_DATA = 0x70412320;  | |||
 // Hide the private key fuses  | |||
 *(u32 *)FUSE_PRIVATEKEYDISABLE = 0x1;  | |||
 u32 crypto_keytable_val = 0xE0;  | |||
 // Clear SE1/SE2 keyslot 0xE (contains the SBK)  | |||
 for (int i = 0; i < 0x7; i++) {  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;  | |||
     crypto_keytable_val++;  | |||
 }  | |||
 crypto_keytable_val = 0xF0;  | |||
 // Clear SE1/SE2 keyslot 0xF (contains the SSK)  | |||
 for (int i = 0; i < 0x07; i++) {  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;  | |||
     crypto_keytable_val++;  | |||
 }  | |||
 crypto_keytable_val = 0xC0;  | |||
 // Clear SE1/SE2 keyslot 0xC (contains the KEK)  | |||
 for (int i = 0; i < 0x7; i++) {  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;  | |||
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;  | |||
     crypto_keytable_val++;  | |||
 }  | |||
 u8 se_instance = 0;          // SE1  | |||
 u8 se_src_key_slot = 0xD;  | |||
 u8 se_src_key_size = 0;      // 128 bits  | |||
 u8 se_dst_key_slot = 0xD;  | |||
 u8 se_dst_key_size = 0;      // 128 bits  | |||
 u8 *se_src_key_data = 0x40004164;  | |||
 // Overwrite SE1 keyslot 0xD (contains the BEK)  | |||
 se_decrypt_key_into_key_slot(se_instance, se_src_key_slot, se_src_key_size, se_dst_key_slot, se_dst_key_size, se_src_key_data);  | |||
 se_instance = 1;             // SE2  | |||
 // Overwrite SE2 keyslot 0xD (contains the BEK)  | |||
 se_decrypt_key_into_key_slot(se_instance, se_src_key_slot, se_src_key_size, se_dst_key_slot, se_dst_key_size, se_src_key_data);  | |||
 /*  | |||
     Untranslated instructions:  | |||
     LDR     R0, =0x4000FC20  | |||
     MOV     R8, R0  | |||
 */  | |||
 return;  | |||
</syntaxhighlight>  | |||
==== IROM patch 7 ====  | |||
This patch doubles the maximum value passed to the function responsible for generating random numbers with the SE. These values are then used for randomizing the duration of wait loops scattered around the bootrom.  | |||
==== IROM patch 8 ====  | |||
This patch forces memcpy to always fall outside of current stack limits.  | |||
==== IROM patch 9 ====  | |||
This patch forces TZRAM to be cleared on any boot type (instead of clearing it only on coldboot).  | |||
= 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.  | How many fuses are expected to be burnt depends the device's unit type as below.  | ||
{| class="wikitable" border="1"  | {| class="wikitable" border="1"  | ||
|-  | |-  | ||
! System version  | ! System version  | ||
! Expected number of burnt fuses (  | ! Expected number of burnt fuses (production)  | ||
! Expected number of burnt fuses (  | ! Expected number of burnt fuses (development)  | ||
|-  | |-  | ||
| 1.0.0  | | 1.0.0  | ||
| 1  | |||
| 0  | |||
|-  | |||
| 2.0.0-2.3.0  | |||
| 2  | |||
| 0  | |||
|-  | |||
| 3.0.0  | |||
| 3  | |||
| 1  | |||
|-  | |||
| 3.0.1-3.0.2  | |||
| 4  | |||
| 1  | |||
|-  | |||
| 4.0.0-4.1.0  | |||
| 5  | |||
| 1  | |||
|-  | |||
| 5.0.0-5.1.0  | |||
| 6  | |||
| 1  | |||
|-  | |||
| 6.0.0-6.1.0  | |||
| 7  | |||
| 1  | |||
|-  | |||
| 6.2.0  | |||
| 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-9.2.0  | |||
| 12  | |||
| 1  | |||
|-  | |||
| 10.0.0-10.2.0  | |||
| 13  | |||
| 1  | |||
|-  | |||
| 11.0.0-12.0.1  | |||
| 14  | |||
| 1  | |||
|-  | |||
| 12.0.2-13.1.0  | |||
| 15  | |||
| 1  | |||
|-  | |||
| 13.2.1-14.1.2  | |||
| 16  | |||
| 1  | | 1  | ||
|-  | |-  | ||
|   | | 15.0.0-15.0.1  | ||
| 17  | |||
|   | |||
| 1  | | 1  | ||
|-  | |-  | ||
|   | | 16.0.0-16.1.0  | ||
|   | | 18  | ||
| 1  | | 1  | ||
|-  | |-  | ||
|   | | 17.0.0-18.1.0  | ||
|   | | 19  | ||
| 1  | | 1  | ||
|-  | |-  | ||
|   | | 19.0.0-19.0.1  | ||
|   | | 20  | ||
| 1  | | 1  | ||
|-  | |-  | ||
|   | | 20.0.0-20.5.0  | ||
|   | | 21  | ||
| 1  | | 1  | ||
|}  | |}  | ||
| Line 1,362: | Line 3,905: | ||
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   | 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.  | ||
Latest revision as of 04:08, 30 September 2025
The Nintendo Switch uses the Tegra's fuse driver for accessing one time programmable data.
Registers
The fuse driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming.
Erista
Registers from 0x7000F800 to 0x7000F800 + 0xFC represent the actual fuse driver which can be used to directly program the hardware fuse bitmap.
Registers from 0x7000F800 + 0x100 (FUSE_CHIP_REG_START_OFFSET) to 0x7000F800 + 0x3FC (FUSE_CHIP_REG_END_OFFSET) represent the fuse cache which holds the sensed values of certain fuses.
Driver
| Name | Address | 
|---|---|
| FUSE_FUSECTRL | 0x7000F800 | 
| FUSE_FUSEADDR | 0x7000F804 | 
| FUSE_FUSERDATA | 0x7000F808 | 
| FUSE_FUSEWDATA | 0x7000F80C | 
| FUSE_FUSETIME_RD1 | 0x7000F810 | 
| FUSE_FUSETIME_RD2 | 0x7000F814 | 
| FUSE_FUSETIME_PGM1 | 0x7000F818 | 
| FUSE_FUSETIME_PGM2 | 0x7000F81C | 
| FUSE_PRIV2INTFC_START | 0x7000F820 | 
| FUSE_FUSEBYPASS | 0x7000F824 | 
| FUSE_PRIVATEKEYDISABLE | 0x7000F828 | 
| FUSE_DISABLEREGPROGRAM | 0x7000F82C | 
| FUSE_WRITE_ACCESS_SW | 0x7000F830 | 
| FUSE_PRIV2RESHIFT | 0x7000F83C | 
| FUSE_FUSETIME_RD3 | 0x7000F84C | 
| FUSE_PRIVATE_KEY0_NONZERO | 0x7000F880 | 
| FUSE_PRIVATE_KEY1_NONZERO | 0x7000F884 | 
| FUSE_PRIVATE_KEY2_NONZERO | 0x7000F888 | 
| FUSE_PRIVATE_KEY3_NONZERO | 0x7000F88C | 
| FUSE_PRIVATE_KEY4_NONZERO | 0x7000F890 | 
FUSE_FUSECTRL
| Bits | Description | 
|---|---|
| 0-1 | FUSE_FUSECTRL_CMD
0x00: IDLE 0x01: READ 0x02: WRITE 0x03: SENSE_CTRL  | 
| 16-20 | 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 | FUSE_FUSECTRL_PD_CTRL | 
| 30 | 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 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 allows accessing the RIR (redundant information row).
FUSE_FUSECTRL_TRCS allows accessing the TRCS (test rows and columns).
FUSE_FUSECTRL_AT1 selects the TRCS test column (always 0).
FUSE_FUSECTRL_AT0 selects the TRCS test row (0 or 1).
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 record shifting is completed.
FUSE_FUSEADDR
| Bits | Description | 
|---|---|
| 0-7 | FUSE_FUSEADDR_VLDFLD | 
Takes the address of the fuse to be read/written/sensed.
FUSE_FUSERDATA
| Bits | Description | 
|---|---|
| 0-31 | FUSE_FUSERDATA_DATA | 
Returns the value read from the fuse.
FUSE_FUSEWDATA
| Bits | Description | 
|---|---|
| 0-31 | FUSE_FUSEWDATA_DATA | 
Takes the value to be written to the fuse.
FUSE_FUSETIME_RD1
| 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 STATE_READ_SETUP.
FUSE_FUSETIME_RD1_TSUR_FUSEOUT takes the time to spend on STATE_SAMPLE_FUSES.
FUSE_FUSETIME_RD1_THR_MAX takes the maximum time for STATE_READ_HOLD.
FUSE_FUSETIME_RD2
| Bits | Description | 
|---|---|
| 0-15 | FUSE_FUSETIME_RD2_TWIDTH_RD | 
Takes the read strobe pulse width used during STATE_READ_STROBE.
FUSE_FUSETIME_PGM1
| 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 | 
FUSE_FUSETIME_PGM1_TSUP_MAX takes the maximum time for STATE_WRITE_SETUP.
FUSE_FUSETIME_PGM1_TSUP_ADDR takes the time to spend on STATE_WRITE_ADDR_SETUP.
FUSE_FUSETIME_PGM1_THP_ADDR takes the time to spend on STATE_WRITE_ADDR_HOLD.
FUSE_FUSETIME_PGM1_THP_PS takes the time to spend on STATE_FUSE_SRC_HOLD.
FUSE_FUSETIME_PGM2
| 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 STATE_WRITE_PROGRAM.
FUSE_FUSETIME_PGM2_TSUP_PS takes the time to spend on STATE_FUSE_SRC_SETUP.
FUSE_FUSETIME_PGM2_THP_CSPS takes the time to spend on STATE_READ_BEFORE_WRITE_SETUP.
FUSE_PRIV2INTFC_START
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIV2INTFC_START_DATA | 
| 1 | FUSE_PRIV2INTFC_SKIP_RECORDS | 
Controls the interface between the internal fuse chip (INTFC) and the fuse cache registers (PRIV).
FUSE_FUSEBYPASS
| Bits | Description | 
|---|---|
| 0 | FUSE_FUSEBYPASS_VAL | 
If set, this register enables fuse bypass mode. This is only available in hardware where the production_mode fuse remains unburnt.
FUSE_PRIVATEKEYDISABLE
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATEKEYDISABLE_VAL | 
| 4 | FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT_VAL | 
If set, this register hides the private_key fuses until the next reset.
FUSE_DISABLEREGPROGRAM
| Bits | Description | 
|---|---|
| 0 | FUSE_DISABLEREGPROGRAM_VAL | 
If set, this register disables fuse programming until the next reset.
FUSE_WRITE_ACCESS_SW
| 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_PRIV2RESHIFT
| 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 record shift (RESHIFT) hardware block used for RAM re-repair.
FUSE_FUSETIME_RD3
| Bits | Description | 
|---|---|
| 0-15 | FUSE_FUSETIME_RD3_TSUR_PDCS | 
Takes the time to spend on STATE_READ_DEASSERT_PD.
FUSE_PRIVATE_KEY0_NONZERO
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATE_KEY0_NONZERO_DATA | 
Returns whether private_key0 is empty or not.
FUSE_PRIVATE_KEY1_NONZERO
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATE_KEY1_NONZERO_DATA | 
Returns whether private_key1 is empty or not.
FUSE_PRIVATE_KEY2_NONZERO
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATE_KEY2_NONZERO_DATA | 
Returns whether private_key2 is empty or not.
FUSE_PRIVATE_KEY3_NONZERO
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATE_KEY3_NONZERO_DATA | 
Returns whether private_key3 is empty or not.
FUSE_PRIVATE_KEY4_NONZERO
| Bits | Description | 
|---|---|
| 0 | FUSE_PRIVATE_KEY4_NONZERO_DATA | 
Returns whether private_key4 is empty or not.
Cache
| Name | Address | 
|---|---|
| FUSE_PRODUCTION_MODE | 0x7000F900 | 
| FUSE_JTAG_SECUREID_VALID | 0x7000F904 | 
| FUSE_ODM_LOCK | 0x7000F908 | 
| FUSE_OPT_OPENGL_EN | 0x7000F90C | 
| FUSE_SKU_INFO | 0x7000F910 | 
| FUSE_CPU_SPEEDO_0_CALIB | 0x7000F914 | 
| FUSE_CPU_IDDQ_CALIB | 0x7000F918 | 
| FUSE_OPT_FT_REV | 0x7000F928 | 
| FUSE_CPU_SPEEDO_1_CALIB | 0x7000F92C | 
| FUSE_CPU_SPEEDO_2_CALIB | 0x7000F930 | 
| FUSE_SOC_SPEEDO_0_CALIB | 0x7000F934 | 
| FUSE_SOC_SPEEDO_1_CALIB | 0x7000F938 | 
| FUSE_SOC_SPEEDO_2_CALIB | 0x7000F93C | 
| FUSE_SOC_IDDQ_CALIB | 0x7000F940 | 
| FUSE_FA | 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_KEY0 | 0x7000F964 | 
| FUSE_PUBLIC_KEY1 | 0x7000F968 | 
| FUSE_PUBLIC_KEY2 | 0x7000F96C | 
| FUSE_PUBLIC_KEY3 | 0x7000F970 | 
| FUSE_PUBLIC_KEY4 | 0x7000F974 | 
| FUSE_PUBLIC_KEY5 | 0x7000F978 | 
| FUSE_PUBLIC_KEY6 | 0x7000F97C | 
| FUSE_PUBLIC_KEY7 | 0x7000F980 | 
| FUSE_TSENSOR1_CALIB | 0x7000F984 | 
| FUSE_TSENSOR2_CALIB | 0x7000F988 | 
| FUSE_OPT_CP_REV | 0x7000F990 | 
| FUSE_OPT_PFG | 0x7000F994 | 
| FUSE_TSENSOR0_CALIB | 0x7000F998 | 
| FUSE_FIRST_BOOTROM_PATCH_SIZE | 0x7000F99C | 
| FUSE_SECURITY_MODE | 0x7000F9A0 | 
| FUSE_PRIVATE_KEY0 | 0x7000F9A4 | 
| FUSE_PRIVATE_KEY1 | 0x7000F9A8 | 
| FUSE_PRIVATE_KEY2 | 0x7000F9AC | 
| FUSE_PRIVATE_KEY3 | 0x7000F9B0 | 
| FUSE_PRIVATE_KEY4 | 0x7000F9B4 | 
| FUSE_ARM_JTAG_DIS | 0x7000F9B8 | 
| FUSE_BOOT_DEVICE_INFO | 0x7000F9BC | 
| FUSE_RESERVED_SW | 0x7000F9C0 | 
| FUSE_OPT_VP9_DISABLE | 0x7000F9C4 | 
| FUSE_RESERVED_ODM0 | 0x7000F9C8 | 
| FUSE_RESERVED_ODM1 | 0x7000F9CC | 
| FUSE_RESERVED_ODM2 | 0x7000F9D0 | 
| FUSE_RESERVED_ODM3 | 0x7000F9D4 | 
| FUSE_RESERVED_ODM4 | 0x7000F9D8 | 
| FUSE_RESERVED_ODM5 | 0x7000F9DC | 
| FUSE_RESERVED_ODM6 | 0x7000F9E0 | 
| FUSE_RESERVED_ODM7 | 0x7000F9E4 | 
| FUSE_OBS_DIS | 0x7000F9E8 | 
| FUSE_USB_CALIB | 0x7000F9F0 | 
| FUSE_SKU_DIRECT_CONFIG | 0x7000F9F4 | 
| FUSE_KFUSE_PRIVKEY_CTRL | 0x7000F9F8 | 
| FUSE_PACKAGE_INFO | 0x7000F9FC | 
| FUSE_OPT_VENDOR_CODE | 0x7000FA00 | 
| FUSE_OPT_FAB_CODE | 0x7000FA04 | 
| FUSE_OPT_LOT_CODE_0 | 0x7000FA08 | 
| FUSE_OPT_LOT_CODE_1 | 0x7000FA0C | 
| FUSE_OPT_WAFER_ID | 0x7000FA10 | 
| FUSE_OPT_X_COORDINATE | 0x7000FA14 | 
| FUSE_OPT_Y_COORDINATE | 0x7000FA18 | 
| FUSE_OPT_SEC_DEBUG_EN | 0x7000FA1C | 
| FUSE_OPT_OPS_RESERVED | 0x7000FA20 | 
| FUSE_SATA_CALIB | 0x7000FA24 | 
| FUSE_GPU_IDDQ_CALIB | 0x7000FA28 | 
| FUSE_TSENSOR3_CALIB | 0x7000FA2C | 
| FUSE_CLOCK_BOUNDOUT0 | 0x7000FA30 | 
| FUSE_CLOCK_BOUNDOUT1 | 0x7000FA34 | 
| FUSE_OPT_SAMPLE_TYPE | 0x7000FA44 | 
| FUSE_OPT_SUBREVISION | 0x7000FA48 | 
| FUSE_OPT_SW_RESERVED_0 | 0x7000FA4C | 
| FUSE_OPT_SW_RESERVED_1 | 0x7000FA50 | 
| FUSE_TSENSOR4_CALIB | 0x7000FA54 | 
| FUSE_TSENSOR5_CALIB | 0x7000FA58 | 
| FUSE_TSENSOR6_CALIB | 0x7000FA5C | 
| FUSE_TSENSOR7_CALIB | 0x7000FA60 | 
| FUSE_OPT_PRIV_SEC_DIS | 0x7000FA64 | 
| FUSE_PKC_DISABLE | 0x7000FA68 | 
| FUSE_FUSE2TSEC_DEBUG_DISABLE | 0x7000FA7C | 
| FUSE_TSENSOR_COMMON | 0x7000FA80 | 
| 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 | 
| 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 | 
| FUSE_VMIN_CALIBRATION | 0x7000FADC | 
| FUSE_AGING_SENSOR_CALIBRATION | 0x7000FAE0 | 
| FUSE_DEBUG_AUTHENTICATION | 0x7000FAE4 | 
| FUSE_SECURE_PROVISION_INDEX | 0x7000FAE8 | 
| FUSE_SECURE_PROVISION_INFO | 0x7000FAEC | 
| FUSE_OPT_GPU_DISABLE_CP1 | 0x7000FAF0 | 
| FUSE_SPARE_ENDIS | 0x7000FAF4 | 
| FUSE_ECO_RESERVE_0 | 0x7000FAF8 | 
| FUSE_RESERVED_CALIB0 | 0x7000FB04 | 
| FUSE_RESERVED_CALIB1 | 0x7000FB08 | 
| FUSE_OPT_GPU_TPC0_DISABLE | 0x7000FB0C | 
| FUSE_OPT_GPU_TPC0_DISABLE_CP1 | 0x7000FB10 | 
| FUSE_OPT_CPU_DISABLE | 0x7000FB14 | 
| FUSE_OPT_CPU_DISABLE_CP1 | 0x7000FB18 | 
| FUSE_TSENSOR10_CALIB | 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 | 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 | 0x7000FB50 | 
| FUSE_RESERVED_FIELD | 0x7000FB54 | 
| FUSE_SPARE_REALIGNMENT_REG | 0x7000FB7C | 
| FUSE_SPARE_BIT_0 | 0x7000FB80 | 
| FUSE_SPARE_BIT_1 | 0x7000FB84 | 
| FUSE_SPARE_BIT_2 | 0x7000FB88 | 
| FUSE_SPARE_BIT_3 | 0x7000FB8C | 
| FUSE_SPARE_BIT_4 | 0x7000FB90 | 
| FUSE_SPARE_BIT_5 | 0x7000FB94 | 
| FUSE_SPARE_BIT_6 | 0x7000FB98 | 
| FUSE_SPARE_BIT_7 | 0x7000FB9C | 
| FUSE_SPARE_BIT_8 | 0x7000FBA0 | 
| FUSE_SPARE_BIT_9 | 0x7000FBA4 | 
| FUSE_SPARE_BIT_10 | 0x7000FBA8 | 
| FUSE_SPARE_BIT_11 | 0x7000FBAC | 
| FUSE_SPARE_BIT_12 | 0x7000FBB0 | 
| FUSE_SPARE_BIT_13 | 0x7000FBB4 | 
| FUSE_SPARE_BIT_14 | 0x7000FBB8 | 
| FUSE_SPARE_BIT_15 | 0x7000FBBC | 
| FUSE_SPARE_BIT_16 | 0x7000FBC0 | 
| 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 | 
| FUSE_SPARE_BIT_30 | 0x7000FBF8 | 
| FUSE_SPARE_BIT_31 | 0x7000FBFC | 
FUSE_SKU_INFO
Stores the SKU ID (must be 0x83).
FUSE_OPT_FT_REV
Stores the FT (Final Test) revision.
Original Erista units have this value set to 0xA0 (revision 5.0). The first batch of patched Erista units have this value set to 0xC0 (revision 6.0). The second batch of patched Erista units have this value set to 0xE0 (revision 7.0).
Mariko and Lite units have this value set to 0x60 (revision 3.0). OLED units have this value set to 0x81 (revision 4.1).
FUSE_SOC_SPEEDO_1_CALIB
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 Erista units have this value set to 0xA0 (revision 5.0). Patched Erista units have this value set to 0x103 (revision 8.3).
Mariko units have this value set to 0x40 (revision 2.0). Lite units have this value set to 0x41 (revision 2.1). OLED units have this value set to 0x100 (revision 8.0).
FUSE_PRIVATE_KEY
Stores the 160-bit private key (128 bit SBK + 32-bit device key).
Reads to these registers after FUSE_PRIVATEKEYDISABLE is set produce all-FF output.
FUSE_ARM_JTAG_DIS
Controls access to the Arm JTAG interface.
Production Erista and Mariko units have this value set to 0x1, while development Erista and Mariko units do not.
FUSE_RESERVED_SW
| Bits | Description | 
|---|---|
| 0-2 | Boot device | 
| 3 | Skip device selection straps | 
| 4 | Enable charger detection | 
| 5 | Enable watchdog | 
| 6 | Forced RCM two button mode (0 = VOLUME_UP, 1 = VOLUME_UP + HOME) | 
| 7 | RCM USB controller mode (0 = USB 2.0, 1 = XUSB) | 
Stores software reserved configuration values.
Production Erista and Mariko units have the forced RCM two button mode set, while development Erista and Mariko units do not.
Original Erista units have the RCM USB controller mode set to USB 2.0, while the first batch of patched Erista units have the RCM USB controller mode set to XUSB. Mariko ignores this and uses XUSB regardless for RCM.
FUSE_RESERVED_ODM0
| Bits | Description | 
|---|---|
| 0-31 | OdmTestId0 | 
FUSE_RESERVED_ODM1
| Bits | Description | 
|---|---|
| 0-31 | OdmTestId1 | 
FUSE_RESERVED_ODM2
| Bits | Description | 
|---|---|
| 0-31 | OdmTestId2 | 
[5.0.0+] If FormatVersion is 1, this becomes:
| Bits | Description | 
|---|---|
| 0-4 | DeviceUniqueKeyGeneration | 
| 5-31 | Reserved | 
FUSE_RESERVED_ODM3
| Bits | Description | 
|---|---|
| 0-31 | OdmTestId3 | 
[5.0.0+] If FormatVersion is 1, this becomes:
| Bits | Description | 
|---|---|
| 0-31 | Reserved | 
FUSE_RESERVED_ODM4
| Bits | Description | 
|---|---|
| 0-1 | HardwareState1 | 
| 2 | HardwareType1 | 
| [1.0.0-3.0.2] 3-5
 [4.0.0+] 3-7  | 
[15.0.0+] DramId1 ([4.0.0-14.1.2] DramId) | 
| 8 | HardwareType2 | 
| 9 | HardwareState2 | 
| 10 | [3.0.0+] QuestState | 
| 11 | [5.0.0+] FormatVersion | 
| 12-14 | [15.0.0+] DramId2 | 
| 16-19 | [4.0.0+] HardwareType3 | 
Stores device configuration parameters.
FUSE_RESERVED_ODM5
Empty and unused.
FUSE_RESERVED_ODM6
Returns the value of the reserved_odm6 anti-downgrade fuse.
FUSE_RESERVED_ODM7
Returns the value of the reserved_odm7 anti-downgrade fuse.
FUSE_SKU_DIRECT_CONFIG
| Bits | Description | 
|---|---|
| 0 | Disable SCPU | 
| 1 | Disable FCPU0 | 
| 2 | Disable FCPU1 | 
| 3 | Disable FCPU2 | 
| 4 | Disable FCPU3 | 
| 5 | Disable all CPUs | 
Controls which CPUs can be used.
Erista units have this value set to 0x00 (both Cortex-A53 and Cortex-A57 clusters are usable).
Mariko units have this value set to 0x01 (only the Cortex-A57 cluster is usable).
FUSE_OPT_SEC_DEBUG_EN
Controls the Falcon SCP debug mode.
FUSE_OPT_PRIV_SEC_DIS
Controls the Falcon Light Secure feature.
FUSE_PKC_DISABLE
Returns if public key crypto is used or not.
FUSE_ODM_INFO
| Bits | Description | 
|---|---|
| 0-7 | Reserved | 
| 8 | Disable DBGEN | 
| 9 | Disable NIDEN | 
| 10 | Disable SPIDEN | 
| 11 | Disable SPNIDEN | 
| 12 | Disable DEVICEEN | 
Production Erista and Mariko units have this value set to 0x1F00 (all signals disabled).
Development Erista and Mariko units have this value set to 0x0000 (all signals enabled).
FUSE_ECO_RESERVE_0
Returns the chip unique AID.
FUSE_SPARE_BIT_2
| Bits | Description | 
|---|---|
| 0 | Speedo fusing revision | 
FUSE_SPARE_BIT_3
| Bits | Description | 
|---|---|
| 0 | Speedo fusing revision | 
FUSE_SPARE_BIT_4
| Bits | Description | 
|---|---|
| 0 | Speedo fusing revision | 
FUSE_SPARE_BIT_5
Must be non-zero on production 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 production 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 which can be used to directly program the hardware fuse bitmap.
Registers from 0x7000F800 + 0x98 to 0x7000F800 + 0x3FC represent the fuse cache which holds the sensed values of certain fuses.
Driver
| Name | Address | 
|---|---|
| FUSE_FUSECTRL | 0x7000F800 | 
| FUSE_FUSEADDR | 0x7000F804 | 
| FUSE_FUSERDATA | 0x7000F808 | 
| FUSE_FUSEWDATA | 0x7000F80C | 
| FUSE_FUSETIME_RD1 | 0x7000F810 | 
| FUSE_FUSETIME_RD2 | 0x7000F814 | 
| FUSE_FUSETIME_PGM1 | 0x7000F818 | 
| FUSE_FUSETIME_PGM2 | 0x7000F81C | 
| FUSE_PRIV2INTFC_START | 0x7000F820 | 
| FUSE_FUSEBYPASS | 0x7000F824 | 
| FUSE_PRIVATEKEYDISABLE | 0x7000F828 | 
| FUSE_DISABLEREGPROGRAM | 0x7000F82C | 
| FUSE_WRITE_ACCESS_SW | 0x7000F830 | 
| FUSE_PRIV2RESHIFT | 0x7000F83C | 
| FUSE_FUSETIME_RD3 | 0x7000F84C | 
| FUSE_SPARE_ADDR_START | 0x7000F860 | 
| FUSE_PRIVATE_KEY0_NONZERO | 0x7000F880 | 
| FUSE_PRIVATE_KEY1_NONZERO | 0x7000F884 | 
| FUSE_PRIVATE_KEY2_NONZERO | 0x7000F888 | 
| FUSE_PRIVATE_KEY3_NONZERO | 0x7000F88C | 
| FUSE_PRIVATE_KEY4_NONZERO | 0x7000F890 | 
FUSE_SPARE_ADDR_START
| Bits | Description | 
|---|---|
| 0-31 | FUSE_SPARE_ADDR_START_DATA | 
Returns the offset of the spare bit fuse registers (always 0x380).
Cache
| Name | Address | 
|---|---|
| FUSE_RESERVED_ODM8 | 0x7000F898 | 
| FUSE_RESERVED_ODM9 | 0x7000F89C | 
| FUSE_RESERVED_ODM10 | 0x7000F8A0 | 
| FUSE_RESERVED_ODM11 | 0x7000F8A4 | 
| FUSE_RESERVED_ODM12 | 0x7000F8A8 | 
| FUSE_RESERVED_ODM13 | 0x7000F8AC | 
| FUSE_RESERVED_ODM14 | 0x7000F8B0 | 
| FUSE_RESERVED_ODM15 | 0x7000F8B4 | 
| FUSE_RESERVED_ODM16 | 0x7000F8B8 | 
| FUSE_RESERVED_ODM17 | 0x7000F8BC | 
| FUSE_RESERVED_ODM18 | 0x7000F8C0 | 
| FUSE_RESERVED_ODM19 | 0x7000F8C4 | 
| FUSE_RESERVED_ODM20 | 0x7000F8C8 | 
| FUSE_RESERVED_ODM21 | 0x7000F8CC | 
| FUSE_KEK00 | 0x7000F8D0 | 
| FUSE_KEK01 | 0x7000F8D4 | 
| FUSE_KEK02 | 0x7000F8D8 | 
| FUSE_KEK03 | 0x7000F8DC | 
| FUSE_BEK00 | 0x7000F8E0 | 
| FUSE_BEK01 | 0x7000F8E4 | 
| FUSE_BEK02 | 0x7000F8E8 | 
| FUSE_BEK03 | 0x7000F8EC | 
| FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT | 0x7000F8F0 | 
| FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT | 0x7000F8F4 | 
| FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT | 0x7000F8F8 | 
| FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT | 0x7000F8FC | 
| FUSE_PRODUCTION_MODE | 0x7000F900 | 
| FUSE_JTAG_SECUREID_VALID | 0x7000F904 | 
| FUSE_ODM_LOCK | 0x7000F908 | 
| FUSE_OPT_OPENGL_EN | 0x7000F90C | 
| FUSE_SKU_INFO | 0x7000F910 | 
| FUSE_CPU_SPEEDO_0_CALIB | 0x7000F914 | 
| FUSE_CPU_IDDQ_CALIB | 0x7000F918 | 
| FUSE_RESERVED_ODM22 | 0x7000F91C | 
| FUSE_RESERVED_ODM23 | 0x7000F920 | 
| FUSE_RESERVED_ODM24 | 0x7000F924 | 
| FUSE_OPT_FT_REV | 0x7000F928 | 
| FUSE_CPU_SPEEDO_1_CALIB | 0x7000F92C | 
| FUSE_CPU_SPEEDO_2_CALIB | 0x7000F930 | 
| FUSE_SOC_SPEEDO_0_CALIB | 0x7000F934 | 
| FUSE_SOC_SPEEDO_1_CALIB | 0x7000F938 | 
| FUSE_SOC_SPEEDO_2_CALIB | 0x7000F93C | 
| FUSE_SOC_IDDQ_CALIB | 0x7000F940 | 
| FUSE_RESERVED_ODM25 | 0x7000F944 | 
| FUSE_FA | 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_KEY0 | 0x7000F964 | 
| FUSE_PUBLIC_KEY1 | 0x7000F968 | 
| FUSE_PUBLIC_KEY2 | 0x7000F96C | 
| FUSE_PUBLIC_KEY3 | 0x7000F970 | 
| FUSE_PUBLIC_KEY4 | 0x7000F974 | 
| FUSE_PUBLIC_KEY5 | 0x7000F978 | 
| FUSE_PUBLIC_KEY6 | 0x7000F97C | 
| FUSE_PUBLIC_KEY7 | 0x7000F980 | 
| FUSE_TSENSOR1_CALIB | 0x7000F984 | 
| FUSE_TSENSOR2_CALIB | 0x7000F988 | 
| FUSE_OPT_SECURE_SCC_DIS | 0x7000F98C | 
| FUSE_OPT_CP_REV | 0x7000F990 | 
| FUSE_OPT_PFG | 0x7000F994 | 
| FUSE_TSENSOR0_CALIB | 0x7000F998 | 
| FUSE_FIRST_BOOTROM_PATCH_SIZE | 0x7000F99C | 
| FUSE_SECURITY_MODE | 0x7000F9A0 | 
| FUSE_PRIVATE_KEY0 | 0x7000F9A4 | 
| FUSE_PRIVATE_KEY1 | 0x7000F9A8 | 
| FUSE_PRIVATE_KEY2 | 0x7000F9AC | 
| FUSE_PRIVATE_KEY3 | 0x7000F9B0 | 
| FUSE_PRIVATE_KEY4 | 0x7000F9B4 | 
| FUSE_ARM_JTAG_DIS | 0x7000F9B8 | 
| FUSE_BOOT_DEVICE_INFO | 0x7000F9BC | 
| FUSE_RESERVED_SW | 0x7000F9C0 | 
| FUSE_OPT_VP9_DISABLE | 0x7000F9C4 | 
| FUSE_RESERVED_ODM0 | 0x7000F9C8 | 
| FUSE_RESERVED_ODM1 | 0x7000F9CC | 
| FUSE_RESERVED_ODM2 | 0x7000F9D0 | 
| FUSE_RESERVED_ODM3 | 0x7000F9D4 | 
| FUSE_RESERVED_ODM4 | 0x7000F9D8 | 
| FUSE_RESERVED_ODM5 | 0x7000F9DC | 
| FUSE_RESERVED_ODM6 | 0x7000F9E0 | 
| FUSE_RESERVED_ODM7 | 0x7000F9E4 | 
| FUSE_OBS_DIS | 0x7000F9E8 | 
| FUSE_OPT_NVJTAG_PROTECTION_ENABLE | 0x7000F9EC | 
| FUSE_USB_CALIB | 0x7000F9F0 | 
| FUSE_SKU_DIRECT_CONFIG | 0x7000F9F4 | 
| FUSE_KFUSE_PRIVKEY_CTRL | 0x7000F9F8 | 
| FUSE_PACKAGE_INFO | 0x7000F9FC | 
| FUSE_OPT_VENDOR_CODE | 0x7000FA00 | 
| FUSE_OPT_FAB_CODE | 0x7000FA04 | 
| FUSE_OPT_LOT_CODE_0 | 0x7000FA08 | 
| FUSE_OPT_LOT_CODE_1 | 0x7000FA0C | 
| FUSE_OPT_WAFER_ID | 0x7000FA10 | 
| FUSE_OPT_X_COORDINATE | 0x7000FA14 | 
| FUSE_OPT_Y_COORDINATE | 0x7000FA18 | 
| FUSE_OPT_SEC_DEBUG_EN | 0x7000FA1C | 
| FUSE_OPT_OPS_RESERVED | 0x7000FA20 | 
| 0x7000FA24 | |
| FUSE_GPU_IDDQ_CALIB | 0x7000FA28 | 
| FUSE_TSENSOR3_CALIB | 0x7000FA2C | 
| FUSE_CLOCK_BONDOUT0 | 0x7000FA30 | 
| FUSE_CLOCK_BONDOUT1 | 0x7000FA34 | 
| FUSE_RESERVED_ODM26 | 0x7000FA38 | 
| FUSE_RESERVED_ODM27 | 0x7000FA3C | 
| FUSE_RESERVED_ODM28 | 0x7000FA40 | 
| FUSE_OPT_SAMPLE_TYPE | 0x7000FA44 | 
| FUSE_OPT_SUBREVISION | 0x7000FA48 | 
| FUSE_OPT_SW_RESERVED_0 | 0x7000FA4C | 
| FUSE_OPT_SW_RESERVED_1 | 0x7000FA50 | 
| FUSE_TSENSOR4_CALIB | 0x7000FA54 | 
| FUSE_TSENSOR5_CALIB | 0x7000FA58 | 
| FUSE_TSENSOR6_CALIB | 0x7000FA5C | 
| FUSE_TSENSOR7_CALIB | 0x7000FA60 | 
| FUSE_OPT_PRIV_SEC_DIS | 0x7000FA64 | 
| FUSE_BOOT_SECURITY_INFO | 0x7000FA68 | 
| FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT | 0x7000FA6C | 
| FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT | 0x7000FA70 | 
| FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT | 0x7000FA74 | 
| FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT | 0x7000FA78 | 
| FUSE_FUSE2TSEC_DEBUG_DISABLE | 0x7000FA7C | 
| FUSE_TSENSOR_COMMON | 0x7000FA80 | 
| FUSE_OPT_CP_BIN | 0x7000FA84 | 
| FUSE_OPT_GPU_DISABLE | 0x7000FA88 | 
| FUSE_OPT_FT_BIN | 0x7000FA8C | 
| FUSE_OPT_DONE_MAP | 0x7000FA90 | 
| FUSE_RESERVED_ODM29 | 0x7000FA94 | 
| FUSE_APB2JTAG_DISABLE | 0x7000FA98 | 
| FUSE_ODM_INFO | 0x7000FA9C | 
| FUSE_ARM_CRYPT_DE_FEATURE | 0x7000FAA8 | 
| FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT | 0x7000FAB0 | 
| FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT | 0x7000FAB4 | 
| FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT | 0x7000FAB8 | 
| FUSE_OPT_RAM_KP_TSMCDP_PO4SVT | 0x7000FABC | 
| 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 | 
| FUSE_VMIN_CALIBRATION | 0x7000FADC | 
| FUSE_AGING_SENSOR_CALIBRATION | 0x7000FAE0 | 
| FUSE_DEBUG_AUTHENTICATION | 0x7000FAE4 | 
| FUSE_SECURE_PROVISION_INDEX | 0x7000FAE8 | 
| FUSE_SECURE_PROVISION_INFO | 0x7000FAEC | 
| FUSE_OPT_GPU_DISABLE_CP1 | 0x7000FAF0 | 
| FUSE_SPARE_ENDIS | 0x7000FAF4 | 
| FUSE_ECO_RESERVE_0 | 0x7000FAF8 | 
| FUSE_RESERVED_CALIB0 | 0x7000FB04 | 
| FUSE_RESERVED_CALIB1 | 0x7000FB08 | 
| FUSE_OPT_GPU_TPC0_DISABLE | 0x7000FB0C | 
| FUSE_OPT_GPU_TPC0_DISABLE_CP1 | 0x7000FB10 | 
| FUSE_OPT_CPU_DISABLE | 0x7000FB14 | 
| FUSE_OPT_CPU_DISABLE_CP1 | 0x7000FB18 | 
| FUSE_TSENSOR10_CALIB | 0x7000FB1C | 
| FUSE_TSENSOR10_CALIB_AUX | 0x7000FB20 | 
| FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT | 0x7000FB24 | 
| FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT | 0x7000FB28 | 
| FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT | 0x7000FB2C | 
| FUSE_OPT_RAM_KP_TSMCDP_PO4HVT | 0x7000FB30 | 
| 0x7000FB34 | |
| FUSE_OPT_GPU_TPC0_DISABLE_CP2 | 0x7000FB38 | 
| FUSE_OPT_GPU_TPC1_DISABLE | 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 | 0x7000FB50 | 
| FUSE_RESERVED_FIELD | 0x7000FB54 | 
| FUSE_SPARE_REALIGNMENT_REG | 0x7000FB7C | 
| FUSE_SPARE_BIT_0 | 0x7000FB80 | 
| FUSE_SPARE_BIT_1 | 0x7000FB84 | 
| FUSE_SPARE_BIT_2 | 0x7000FB88 | 
| FUSE_SPARE_BIT_3 | 0x7000FB8C | 
| FUSE_SPARE_BIT_4 | 0x7000FB90 | 
| FUSE_SPARE_BIT_5 | 0x7000FB94 | 
| FUSE_SPARE_BIT_6 | 0x7000FB98 | 
| FUSE_SPARE_BIT_7 | 0x7000FB9C | 
| FUSE_SPARE_BIT_8 | 0x7000FBA0 | 
| FUSE_SPARE_BIT_9 | 0x7000FBA4 | 
| FUSE_SPARE_BIT_10 | 0x7000FBA8 | 
| FUSE_SPARE_BIT_11 | 0x7000FBAC | 
| FUSE_SPARE_BIT_12 | 0x7000FBB0 | 
| FUSE_SPARE_BIT_13 | 0x7000FBB4 | 
| FUSE_SPARE_BIT_14 | 0x7000FBB8 | 
| FUSE_SPARE_BIT_15 | 0x7000FBBC | 
| FUSE_SPARE_BIT_16 | 0x7000FBC0 | 
| 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 | 
FUSE_KEK
Stores the 128-bit KEK (Key Encryption Key) encrypted with the FEK (Fuse Encryption Key) selected by FUSE_RESERVED_PRODUCTION and FUSE_BOOT_SECURITY_INFO.
Reads to these registers after FUSE_PRIVATEKEYDISABLE is set produce all-FF output.
FUSE_BEK
Stores the 128-bit BEK (Boot Encryption Key) encrypted with the FEK (Fuse Encryption Key) selected by FUSE_RESERVED_PRODUCTION and FUSE_BOOT_SECURITY_INFO.
Reads to these registers after FUSE_PRIVATEKEYDISABLE is set produce all-FF output.
FUSE_RESERVED_PRODUCTION
| Bits | Description | 
|---|---|
| 0-1 | Reserved | 
| 2 | FEK bank select | 
FUSE_OPT_NVJTAG_PROTECTION_ENABLE
Controls the NVJTAG protection feature. If enabled, this will permanently disable access to all DFT (Design for Test) functions which include the ability put the chip in FA (Failure Analysis) mode.
FUSE_RESERVED_ODM28
| Bits | Description | 
|---|---|
| 0 | RegulatorType | 
FUSE_BOOT_SECURITY_INFO
| Bits | Description | 
|---|---|
| 0-1 | Authentication (0 = AES_CMAC, 1 = PKC_RSA) | 
| 2 | Encryption (0 = DISABLE, 1 = ENABLE) | 
| 3 | Fuse encryption (0 = DISABLE, 1 = ENABLE) | 
| 4-6 | Fuse encryption select (0 = TEST_KEY, 1 = NVIDIA_KEY, 2 to 7 = OEM_KEY_0 to OEM_KEY_5) | 
| 7 | SE atomic context save (0 = DISABLE, 1 = ENABLE) | 
Stores configuration values for the new boot security mechanism.
Mariko units have authentication set to PKC_RSA, encryption enabled, fuse encryption enabled and fuse encryption select set to OEM_KEY_0 (development units) or OEM_KEY_1 (production units).
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, spare bits and all fuses afterwards in the fuse bitmap, no longer have a redundant alias.
Erista
| 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-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 | 58 | 59 | 5-31 | 
| reserved_odm6 | 60 | 61 | 0-4 | 
| reserved_odm7 | 60 | 61 | 5-31 | 
| 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_records | 106 | None | 0-192 | 
| irom_patch | 112 | None | 0-2560 | 
reserved_odm6
Used for anti-downgrade control.
reserved_odm7
Used for anti-downgrade control.
irom_patch
Bootrom patches are burned to the hardware fuse bitmap using a specific format (see 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:
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_A0The 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.
 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;IROM patch 1
This patch sets APBDEV_PMC_SCRATCH190_0 to 0x01, which LP0 resume code expects.
 u32 APBDEV_PMC_SCRATCH190_0 = 0x7000EC18;
 u32 pmc_scratch190_val = *(u32 *)APBDEV_PMC_SCRATCH190_0;
 
 return (pmc_scratch190_val | 0x01);IROM patch 2
This patch adjusts USB configurations.
 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;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 set to revision 7.0) this patch has been replaced with a fix for 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 8 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.
 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;IROM patch 5
This patch adjusts USB configurations.
 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;IROM patch 6
This patch allows controlling the debug authentication configuration using a fuse.
 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;IROM patch 7
This patch prevents overflowing IRAM (0x40010000) when copying the warmboot binary from DRAM.
 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;IROM patch 8
This patch sets the correct warmboot binary entrypoint address for RSA signature verification, which would be done in DRAM instead of IRAM without this patch.
 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;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 SE_TZRAM_SECURITY to be 0x01 instead of restoring it from the saved SE context.
Mariko
| 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_records | 170 | None | 0-192 | 
| irom_patch | 176 | None | 0-2560 | 
irom_patch
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 : svc #0x5b (offset 0xfe)
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                                  ;  8: 0x62e3ef5b 0x0010c5c6 0x0000ef5b : svc #0x5b (offset 0xfe)
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           endsFirst IROM patch
This patch is applied to the bootrom IPATCH handling function so that more patches can be loaded from fuses.
 if (patch_start_addr == 0xAF) {
     patch_start_addr = 0xFF;
 }
 
 patch_start_addr--;
 
 return;IROM patch 0
This patch initializes all unused IRAM memory to 0xEAFFFFFE (infinite loop instruction).
 /*
     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;IROM patch 1
This patch stubs the function responsible for disabling read access for the SE AES keyslots.
Due to a programming mistake, when loading the OEM AES keys the aforementioned function would be called with the wrong arguments. The patch prevents this by simply stubbing the function altogether, which is only acceptable because the Mariko's SE hardware already boots with keyslot reading permanently disabled.
IROM patch 2
This patch forces the function responsible for checking if SE context atomic save is enabled (by checking a fuse) to always return true.
Some Mariko units have been found to not have the relevant fuse bit (bit 7 in FUSE_BOOT_SECURITY_INFO) burned, so the patch serves as a workaround for this.
IROM patch 3
This patch forces a jump to the same routine used by IROM patch 0 if loading a bootloader failed.
By setting all IRAM memory from 0x4000FC20 to 0x40040000 to 0xEAFFFFFE, a bootloader that somehow failed validation is effectively erased from memory.
IROM patch 4
This patch stores a stack cookie (value 0x5A55F0E1) after a RCM message is received and before it's validated.
IROM patch 5
This patch checks the stack cookie stored by IROM patch 4 right after a RCM message is validated.
If the stack cookie's value is still 0x5A55F0E1, the bootrom jumps to a panic. If it changed to anything other than 0, the same routine used by IROM patch 0 is called. Presumably, this is an attempt at mitigating fault injection attacks against skipping the validation of RCM messages.
IROM patch 6
This patch sanitizes the crypto context right before receiving a RCM message.
 u32 FUSE_PRIVATEKEYDISABLE = 0x7000F828;
 u32 SE1_CRYPTO_KEYTABLE_ADDR = 0x7001231C;
 u32 SE2_CRYPTO_KEYTABLE_ADDR = 0x7041231C;
 u32 SE1_CRYPTO_KEYTABLE_DATA = 0x70012320;
 u32 SE2_CRYPTO_KEYTABLE_DATA = 0x70412320;
 
 // Hide the private key fuses
 *(u32 *)FUSE_PRIVATEKEYDISABLE = 0x1;
 
 u32 crypto_keytable_val = 0xE0;
 
 // Clear SE1/SE2 keyslot 0xE (contains the SBK)
 for (int i = 0; i < 0x7; i++) {
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;
     crypto_keytable_val++;
 }
 
 crypto_keytable_val = 0xF0;
 
 // Clear SE1/SE2 keyslot 0xF (contains the SSK)
 for (int i = 0; i < 0x07; i++) {
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;
     crypto_keytable_val++;
 }
 
 crypto_keytable_val = 0xC0;
 
 // Clear SE1/SE2 keyslot 0xC (contains the KEK)
 for (int i = 0; i < 0x7; i++) {
     *(u32 *)SE1_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE1_CRYPTO_KEYTABLE_DATA = 0;
     *(u32 *)SE2_CRYPTO_KEYTABLE_ADDR = crypto_keytable_val;
     *(u32 *)SE2_CRYPTO_KEYTABLE_DATA = 0;
     crypto_keytable_val++;
 }
 
 u8 se_instance = 0;          // SE1
 u8 se_src_key_slot = 0xD;
 u8 se_src_key_size = 0;      // 128 bits
 u8 se_dst_key_slot = 0xD;
 u8 se_dst_key_size = 0;      // 128 bits
 u8 *se_src_key_data = 0x40004164;
 
 // Overwrite SE1 keyslot 0xD (contains the BEK)
 se_decrypt_key_into_key_slot(se_instance, se_src_key_slot, se_src_key_size, se_dst_key_slot, se_dst_key_size, se_src_key_data);
 
 se_instance = 1;             // SE2
 
 // Overwrite SE2 keyslot 0xD (contains the BEK)
 se_decrypt_key_into_key_slot(se_instance, se_src_key_slot, se_src_key_size, se_dst_key_slot, se_dst_key_size, se_src_key_data);
 
 /*
     Untranslated instructions:
 
     LDR     R0, =0x4000FC20
     MOV     R8, R0
 */
 
 return;IROM patch 7
This patch doubles the maximum value passed to the function responsible for generating random numbers with the SE. These values are then used for randomizing the duration of wait loops scattered around the bootrom.
IROM patch 8
This patch forces memcpy to always fall outside of current stack limits.
IROM patch 9
This patch forces TZRAM to be cleared on any boot type (instead of clearing it only on coldboot).
Anti-downgrade
The first bootloader verifies FUSE_RESERVED_ODM7 to prevent downgrading. How many fuses are expected to be burnt depends the device's unit type as below.
| System version | Expected number of burnt fuses (production) | Expected number of burnt fuses (development) | 
|---|---|---|
| 1.0.0 | 1 | 0 | 
| 2.0.0-2.3.0 | 2 | 0 | 
| 3.0.0 | 3 | 1 | 
| 3.0.1-3.0.2 | 4 | 1 | 
| 4.0.0-4.1.0 | 5 | 1 | 
| 5.0.0-5.1.0 | 6 | 1 | 
| 6.0.0-6.1.0 | 7 | 1 | 
| 6.2.0 | 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-9.2.0 | 12 | 1 | 
| 10.0.0-10.2.0 | 13 | 1 | 
| 11.0.0-12.0.1 | 14 | 1 | 
| 12.0.2-13.1.0 | 15 | 1 | 
| 13.2.1-14.1.2 | 16 | 1 | 
| 15.0.0-15.0.1 | 17 | 1 | 
| 16.0.0-16.1.0 | 18 | 1 | 
| 17.0.0-18.1.0 | 19 | 1 | 
| 19.0.0-19.0.1 | 20 | 1 | 
| 20.0.0-20.5.0 | 21 | 1 | 
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 fuses reserved_odm6 and 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. 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.