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