Fuses: Difference between revisions
No edit summary |
No edit summary |
||
| (19 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
The Nintendo Switch makes use of Tegra's fuse driver for a number of operations. This driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming. | The Nintendo Switch makes use of Tegra's fuse driver for a number of operations. This driver is mapped to physical address 0x7000F800 with a total size of 0x400 bytes and exposes several registers for fuse programming. | ||
Registers from 0x7000F800 to 0x7000F800 + 0xFF can be used to directly program the hardware fuse | Registers from 0x7000F800 to 0x7000F800 + 0xFF can be used to directly program the hardware fuse bitmap, while registers from 0x7000F800 + 0x100 (FUSE_CHIP_REG_START_OFFSET) to 0x7000F800 + 0x3FC (FUSE_CHIP_REG_END_OFFSET) represent cached values read from certain fuses. | ||
== Registers == | == Registers == | ||
| Line 11: | Line 11: | ||
! Address | ! Address | ||
|- | |- | ||
| [[# | | [[#FUSE_FUSECTRL|FUSE_FUSECTRL]] | ||
| 0x7000F800 | | 0x7000F800 | ||
|- | |- | ||
| [[# | | [[#FUSE_FUSEADDR|FUSE_FUSEADDR]] | ||
| 0x7000F804 | | 0x7000F804 | ||
|- | |- | ||
| [[# | | [[#FUSE_FUSERDATA|FUSE_FUSERDATA]] | ||
| 0x7000F808 | | 0x7000F808 | ||
|- | |- | ||
| [[# | | [[#FUSE_FUSEWDATA|FUSE_FUSEWDATA]] | ||
| 0x7000F80C | | 0x7000F80C | ||
|- | |- | ||
| | | FUSE_FUSETIME_RD1 | ||
| 0x7000F810 | | 0x7000F810 | ||
|- | |- | ||
| | | FUSE_FUSETIME_RD2 | ||
| 0x7000F814 | | 0x7000F814 | ||
|- | |- | ||
| | | FUSE_FUSETIME_PGM1 | ||
| 0x7000F818 | | 0x7000F818 | ||
|- | |- | ||
| [[# | | [[#FUSE_FUSETIME_PGM2|FUSE_FUSETIME_PGM2]] | ||
| 0x7000F81C | | 0x7000F81C | ||
|- | |- | ||
| [[# | | [[#FUSE_PRIV2INTFC_START|FUSE_PRIV2INTFC_START]] | ||
| 0x7000F820 | | 0x7000F820 | ||
|- | |- | ||
| Line 44: | Line 44: | ||
| 0x7000F828 | | 0x7000F828 | ||
|- | |- | ||
| [[# | | [[#FUSE_DISABLEREGPROGRAM|FUSE_DISABLEREGPROGRAM]] | ||
| 0x7000F82C | | 0x7000F82C | ||
|- | |- | ||
| [[# | | [[#FUSE_WRITE_ACCESS_SW|FUSE_WRITE_ACCESS_SW]] | ||
| 0x7000F830 | | 0x7000F830 | ||
|- | |- | ||
| Line 56: | Line 56: | ||
| 0x7000F83C | | 0x7000F83C | ||
|- | |- | ||
| | | FUSE_FUSETIME_RD3 | ||
| 0x7000F84C | | 0x7000F84C | ||
|- | |- | ||
| Line 75: | Line 75: | ||
|} | |} | ||
==== | ==== FUSE_FUSECTRL ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Bits | ! Bits | ||
| Line 81: | Line 81: | ||
|- | |- | ||
| 0-1 | | 0-1 | ||
| | | FUSE_FUSECTRL_CMD | ||
0x00: IDLE | |||
0x01: READ | |||
0x02: WRITE | |||
0x03: SENSE_CTRL | |||
|- | |- | ||
| 16-20 | | 16-20 | ||
| | | FUSE_FUSECTRL_STATE | ||
0x00: STATE_RESET | |||
0x01: STATE_POST_RESET | |||
0x02: STATE_LOAD_ROW0 | |||
0x03: STATE_LOAD_ROW1 | |||
0x04: STATE_IDLE | |||
0x05: STATE_READ_SETUP | |||
0x06: STATE_READ_STROBE | |||
0x07: STATE_SAMPLE_FUSES | |||
0x08: STATE_READ_HOLD | |||
0x09: STATE_FUSE_SRC_SETUP | |||
0x0A: STATE_WRITE_SETUP | |||
0x0B: STATE_WRITE_ADDR_SETUP | |||
0x0C: STATE_WRITE_PROGRAM | |||
0x0D: STATE_WRITE_ADDR_HOLD | |||
0x0E: STATE_FUSE_SRC_HOLD | |||
0x0F: STATE_LOAD_RIR | |||
0x10: STATE_READ_BEFORE_WRITE_SETUP | |||
0x11: STATE_READ_DEASSERT_PD | |||
|- | |||
| 21 | |||
| FUSE_FUSECTRL_MARGIN_READ | |||
|- | |||
| 22 | |||
| FUSE_FUSECTRL_RWL | |||
|- | |||
| 23 | |||
| FUSE_FUSECTRL_TRCS | |||
|- | |||
| 24 | |||
| FUSE_FUSECTRL_AT1 | |||
|- | |||
| 25 | |||
| FUSE_FUSECTRL_AT0 | |||
|- | |- | ||
| 26 | | 26 | ||
| | | FUSE_FUSECTRL_PD_CTRL | ||
|- | |- | ||
| 30 | | 30 | ||
| | | FUSE_FUSECTRL_FUSE_SENSE_DONE | ||
|- | |||
| 31 | |||
| FUSE_FUSECTRL_RECORD_SHIFT_DONE | |||
|} | |} | ||
Before fuse reading/writing the power down mode must be disabled. | Before fuse reading/writing the power down mode must be disabled. | ||
SENSE_CTRL mode flushes programmed values into the [[Fuses#Cache_registers|cache registers]]. | |||
==== | ==== FUSE_FUSEADDR ==== | ||
This register takes the address of the fuse to be read/written/sensed. | This register takes the address of the fuse to be read/written/sensed. | ||
==== | ==== FUSE_FUSERDATA ==== | ||
This register receives the value read from the fuse. | This register receives the value read from the fuse. | ||
==== | ==== FUSE_FUSEWDATA ==== | ||
This register takes the value to be written to the fuse. | This register takes the value to be written to the fuse. | ||
==== | ==== FUSE_FUSETIME_PGM2 ==== | ||
This register takes the fuse programming pulse (0xC0 == 19200 kHz). | This register takes the fuse programming pulse (0xC0 == 19200 kHz). | ||
==== | ==== FUSE_PRIV2INTFC_START ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Bits | ! Bits | ||
| Line 114: | Line 154: | ||
|- | |- | ||
| 0 | | 0 | ||
| | | FUSE_PRIV2INTFC_START_DATA | ||
|- | |- | ||
| 1 | | 1 | ||
| | | FUSE_PRIV2INTFC_START_SKIP_RECORDS | ||
|} | |} | ||
==== | ==== FUSE_DISABLEREGPROGRAM ==== | ||
If set to 0x01, this register disables fuse programming. | If set to 0x01, this register disables fuse programming. | ||
==== | ==== FUSE_WRITE_ACCESS_SW ==== | ||
If set to 0x01, this register disables software writes to the fuse driver registers. | If set to 0x01, this register disables software writes to the fuse driver registers. | ||
| Line 648: | Line 688: | ||
Stores the FT (Final Test) revision. | Stores the FT (Final Test) revision. | ||
Original launch units have this value set to 0xA0 (revision 5.0). The first batch of patched units have this value set to 0xC0 (revision 6.0). | Original launch units have this value set to 0xA0 (revision 5.0). The first batch of patched units have this value set to 0xC0 (revision 6.0). The second batch of patched units have this value set to 0xE0 (revision 7.0) | ||
==== FUSE_FA ==== | ==== FUSE_FA ==== | ||
| Line 682: | Line 722: | ||
|- | |- | ||
| 0-1 | | 0-1 | ||
| Unit type ( | | Unit type (0x00 = Retail, 0x03 = Debug) | ||
|- | |- | ||
| 2 | | 2 | ||
| | | Production flag (0x00 = Prototype, 0x01 = Production) | ||
|- | |- | ||
| [1.0.0-3.0.2] 3-5 | | [1.0.0-3.0.2] 3-5 | ||
| Line 692: | Line 732: | ||
|- | |- | ||
| 8 | | 8 | ||
| | | Development flag (0x00 = Retail, 0x01 = Development) | ||
|- | |- | ||
| 9 | | 9 | ||
| Unit type | | Unit type flag (0x00 = Debug, 0x01 = Retail) | ||
|- | |- | ||
| 10 | | 10 | ||
| [3.0.0+] Kiosk | | [3.0.0+] Kiosk flag (0x00 = Retail, 0x01 = Kiosk/Quest) | ||
|- | |- | ||
| 11 | | 11 | ||
| [5.0.0+] | | [5.0.0+] Patch flag (0x00 = Unpatched, 1 = Patched) | ||
|- | |- | ||
| 16-19 | | 16-19 | ||
| [4.0.0+] New | | [4.0.0+] New hardware type (0x00 = Icosa, 0x01 = Iowa, 0x02 = Hoag) | ||
|} | |} | ||
| Line 710: | Line 750: | ||
==== FUSE_RESERVED_ODM6 ==== | ==== FUSE_RESERVED_ODM6 ==== | ||
This register returns the value programmed into | This register returns the value programmed into fuse [[#reserved_odm6|reserved_odm6]]. | ||
==== FUSE_RESERVED_ODM7 ==== | ==== FUSE_RESERVED_ODM7 ==== | ||
This register returns the value programmed into | This register returns the value programmed into fuse [[#reserved_odm7|reserved_odm7]]. | ||
==== FUSE_PUBLIC_KEY ==== | ==== FUSE_PUBLIC_KEY ==== | ||
| Line 721: | Line 761: | ||
Stores the CP (Chip Probing) revision. | Stores the CP (Chip Probing) revision. | ||
Original launch units have this value set to 0xA0 (revision 5.0). | Original launch units have this value set to 0xA0 (revision 5.0). Patched units have this value set to 0x103 (revision 8.3). | ||
==== FUSE_PRIVATE_KEY ==== | ==== FUSE_PRIVATE_KEY ==== | ||
| Line 751: | Line 791: | ||
|} | |} | ||
This caches the value of the | This caches the value of the reserved_sw fuse from the hardware bitmap. | ||
Original launch units have the RCM USB controller mode set to USB 2.0, while the first batch of patched units have the RCM USB controller mode set to XUSB. | Original launch units have the RCM USB controller mode set to USB 2.0, while the first batch of patched units have the RCM USB controller mode set to XUSB. | ||
==== FUSE_PKC_DISABLE ==== | ==== FUSE_PKC_DISABLE ==== | ||
This caches the value of the pkc_disable fuse from the hardware | This caches the value of the pkc_disable fuse from the hardware bitmap. | ||
==== FUSE_SPARE_BIT_2 ==== | ==== FUSE_SPARE_BIT_2 ==== | ||
| Line 769: | Line 809: | ||
==== FUSE_SPARE_BIT_5 ==== | ==== FUSE_SPARE_BIT_5 ==== | ||
Must be non-zero on retail units, otherwise the first bootloader panics. | Must be non-zero on retail units, otherwise the first bootloader panics. | ||
On | On prototype units it can be zero, which tells the bootloader to choose from two pre-production master key seeds. If set to non-zero on a prototype unit, it tells the bootloader to choose from two master key seeds (with the second one being the same as the retail master key seed). | ||
[4.0.0+] This value is no longer used during boot. | [4.0.0+] This value is no longer used during boot. | ||
== | == Bitmap == | ||
The actual hardware fuses | The actual hardware fuses are stored in a bitmap and may be programmed through the fuse driver after enabling fuse programming. | ||
Fuse numbers are relative to the start of the fuse bitmap where each element is a 4 byte word and has a redundant alias. A single fuse write operation must always write the same value to '''fuse_bitmap + ((fuse_number + 0) << 2)''' (PRIMARY_ALIAS) and '''fuse_bitmap + ((fuse_number + 1) << 2)''' (REDUNDANT_ALIAS). However, after offset 0x180 in the fuse bitmap, fuses no longer have a redundant alias. | |||
Below is a list of common | Below is a list of common fuses used by Tegra devices (and applicable to the Switch). | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Name | ! Name | ||
! | ! Number | ||
! Redundant number | |||
! Bits | ! Bits | ||
|- | |- | ||
| | | enable_fuse_program | ||
| | | 0 | ||
| 1 | |||
| 0 | |||
|- | |||
| disable_fuse_program | |||
| 0 | |||
| 1 | |||
| 1 | |||
|- | |||
| bypass_fuses | |||
| 0 | |||
| 1 | |||
| 2 | |||
|- | |||
| jtag_direct_access_disable | |||
| 0 | |||
| 1 | | 1 | ||
| 3 | |||
|- | |- | ||
| | | production_mode | ||
| | | 0 | ||
| 1 | | 1 | ||
| 4 | |||
|- | |||
| jtag_secureid_valid | |||
| 0 | |||
| 1 | |||
| 5 | |||
|- | |- | ||
| odm_lock | | odm_lock | ||
| | | 0 | ||
| | | 1 | ||
| 6-9 | |||
|- | |||
| fa_mode | |||
| 0 | |||
| 1 | |||
| 10 | |||
|- | |||
| security_mode | |||
| 0 | |||
| 1 | |||
| 11 | |||
|- | |||
| arm_debug_dis | |||
| 0 | |||
| 1 | |||
| 12 | |||
|- | |||
| obs_dis | |||
| 0 | |||
| 1 | |||
| 13 | |||
|- | |||
| public_key0 | |||
| 10 | |||
| 11 | |||
| 30-31 | |||
|- | |||
| public_key0 | |||
| 12 | |||
| 13 | |||
| 0-29 | |||
|- | |||
| public_key1 | |||
| 12 | |||
| 13 | |||
| 30-31 | |||
|- | |- | ||
| | | public_key1 | ||
| | | 14 | ||
| | | 15 | ||
| 0-29 | |||
|- | |- | ||
| | | public_key2 | ||
| | | 14 | ||
| | | 15 | ||
| 30-31 | |||
|- | |- | ||
| | | public_key2 | ||
| | | 16 | ||
| | | 17 | ||
| 0-29 | |||
|- | |- | ||
| | | public_key3 | ||
| 16 | | 16 | ||
| 17 | |||
| 30-31 | |||
|- | |- | ||
| | | public_key3 | ||
| | | 18 | ||
| 3 | | 19 | ||
| 0-29 | |||
|- | |||
| public_key4 | |||
| 18 | |||
| 19 | |||
| 30-31 | |||
|- | |||
| public_key4 | |||
| 20 | |||
| 21 | |||
| 0-29 | |||
|- | |||
| public_key5 | |||
| 20 | |||
| 21 | |||
| 30-31 | |||
|- | |||
| public_key5 | |||
| 22 | |||
| 23 | |||
| 0-29 | |||
|- | |||
| public_key6 | |||
| 22 | |||
| 23 | |||
| 30-31 | |||
|- | |||
| public_key6 | |||
| 24 | |||
| 25 | |||
| 0-29 | |||
|- | |||
| public_key7 | |||
| 24 | |||
| 25 | |||
| 30-31 | |||
|- | |||
| public_key7 | |||
| 26 | |||
| 27 | |||
| 0-29 | |||
|- | |||
| private_key0 | |||
| 34 | |||
| 35 | |||
| 12-31 | |||
|- | |||
| private_key0 | |||
| 36 | |||
| 37 | |||
| 0-11 | |||
|- | |||
| private_key1 | |||
| 36 | |||
| 37 | |||
| 12-31 | |||
|- | |||
| private_key1 | |||
| 38 | |||
| 39 | |||
| 0-11 | |||
|- | |||
| private_key2 | |||
| 38 | |||
| 39 | |||
| 12-31 | |||
|- | |||
| private_key2 | |||
| 40 | |||
| 41 | |||
| 0-11 | |||
|- | |||
| private_key3 | |||
| 40 | |||
| 41 | |||
| 12-31 | |||
|- | |||
| private_key3 | |||
| 42 | |||
| 43 | |||
| 0-11 | |||
|- | |||
| private_key4 | |||
| 42 | |||
| 43 | |||
| 12-31 | |||
|- | |||
| private_key4 | |||
| 44 | |||
| 45 | |||
| 0-11 | |||
|- | |||
| boot_device_info | |||
| 44 | |||
| 45 | |||
| 12-27 | |||
|- | |||
| reserved_sw | |||
| 44 | |||
| 45 | |||
| 28-31 | |||
|- | |||
| reserved_sw | |||
| 46 | |||
| 47 | |||
| 0-3 | |||
|- | |||
| reserved_odm0 | |||
| 46 | |||
| 47 | |||
| 5-31 | |||
|- | |||
| reserved_odm0 | |||
| 48 | |||
| 49 | |||
| 0-4 | |||
|- | |||
| reserved_odm1 | |||
| 48 | |||
| 49 | |||
| 5-31 | |||
|- | |||
| reserved_odm1 | |||
| 50 | |||
| 51 | |||
| 0-4 | |||
|- | |||
| reserved_odm2 | |||
| 50 | |||
| 51 | |||
| 5-31 | |||
|- | |||
| reserved_odm2 | |||
| 52 | |||
| 53 | |||
| 0-4 | |||
|- | |||
| reserved_odm3 | |||
| 52 | |||
| 53 | |||
| 5-31 | |||
|- | |||
| reserved_odm3 | |||
| 54 | |||
| 55 | |||
| 0-4 | |||
|- | |||
| reserved_odm4 | |||
| 54 | |||
| 55 | |||
| 5-31 | |||
|- | |||
| reserved_odm4 | |||
| 56 | |||
| 57 | |||
| 0-4 | |||
|- | |||
| reserved_odm5 | |||
| 56 | |||
| 57 | |||
| 5-31 | |||
|- | |||
| reserved_odm5 | |||
| 58 | |||
| 59 | |||
| 0-4 | |||
|- | |||
| [[#reserved_odm6|reserved_odm6]] | |||
| 58 | |||
| 59 | |||
| 5-31 | |||
|- | |||
| [[#reserved_odm6|reserved_odm6]] | |||
| 60 | |||
| 61 | |||
| 0-4 | |||
|- | |||
| [[#reserved_odm7|reserved_odm7]] | |||
| 60 | |||
| 61 | |||
| 5-31 | |||
|- | |||
| [[#reserved_odm7|reserved_odm7]] | |||
| 62 | |||
| 63 | |||
| 0-4 | |||
|- | |||
| kfuse_privkey_ctrl | |||
| 64 | |||
| 65 | |||
| 13-14 | |||
|- | |||
| package_info | |||
| 64 | |||
| 65 | |||
| 15-18 | |||
|- | |||
| opt_vendor_code | |||
| 64 | |||
| 65 | |||
| 19-22 | |||
|- | |||
| opt_fab_code | |||
| 64 | |||
| 65 | |||
| 23-28 | |||
|- | |||
| opt_lot_code_0 | |||
| 64 | |||
| 65 | |||
| 29-31 | |||
|- | |||
| opt_lot_code_0 | |||
| 66 | |||
| 67 | |||
| 0-28 | |||
|- | |||
| opt_lot_code_1 | |||
| 66 | |||
| 67 | |||
| 29-31 | |||
|- | |||
| opt_lot_code_1 | |||
| 68 | |||
| 69 | |||
| 0-24 | |||
|- | |||
| opt_wafer_id | |||
| 68 | |||
| 69 | |||
| 25-30 | |||
|- | |||
| opt_x_coordinate | |||
| 68 | |||
| 69 | |||
| 31 | |||
|- | |||
| opt_x_coordinate | |||
| 70 | |||
| 71 | |||
| 0-7 | |||
|- | |||
| opt_y_coordinate | |||
| 70 | |||
| 71 | |||
| 8-16 | |||
|- | |||
| opt_sec_debug_en | |||
| 70 | |||
| 71 | |||
| 17 | |||
|- | |- | ||
| | | opt_ops_reserved | ||
| | | 70 | ||
| | | 71 | ||
| 18-23 | |||
|- | |- | ||
| | | sata_calib | ||
| | | 70 | ||
| | | 71 | ||
| 24-25 | |||
|- | |- | ||
| | | opt_priv_sec_en | ||
| | | 90 | ||
| | | 91 | ||
| 8 | |||
|- | |- | ||
| pkc_disable | | 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 | |||
|- | |- | ||
| aid | | aid | ||
| | | 103 | ||
| | | None | ||
| 0-31 | |||
|- | |- | ||
| [[# | | [[#irom_patch|irom_patch]] | ||
| | | 114 | ||
| | | None | ||
| Variable | |||
|} | |} | ||
=== | === reserved_odm6 === | ||
Used for anti-downgrade control. | |||
=== reserved_odm7 === | |||
Used for anti-downgrade control. | |||
=== | === irom_patch === | ||
Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse | Tegra210 based hardware such as the Switch provides support for bootrom patches. The patch data is burned to the hardware fuse bitmap using a specific format (see [https://gist.github.com/shuffle2/f8728159da100e9df2606d43925de0af shuffle2's ipatch decoder]). The bootrom reads these fuses in order to initialize the IPATCH hardware, which allows overriding data returned for code and data fetches done by BPMP. | ||
The following represents the patch data dumped from a Switch console: | The following represents the patch data dumped from a Switch console: | ||
| Line 858: | Line 1,232: | ||
RAM:00000000 | RAM:00000000 | ||
RAM:00000000 irom_svc_dispatch | RAM:00000000 irom_svc_dispatch | ||
RAM:00000000 STMFD SP!, {R0-R2} ; ipatches: | RAM:00000000 STMFD SP!, {R0-R2} ; ipatches (new): | ||
RAM:00000000 ; 0 b57df00 16ae df00 : svc #0x00 (offset 0x48) | |||
RAM:00000000 ; 1 1820df22 3040 df22 : svc #0x22 (offset 0x8c) | |||
RAM:00000000 ; 2 3797df26 6f2e df26 : svc #0x26 (offset 0x94) | |||
RAM:00000000 ; 3 3b4d2100 769a 2100 : movs r1, #0x00 | |||
RAM:00000000 ; 4 42bdf2c 856 df2c : svc #0x2c (offset 0xa0) | |||
RAM:00000000 ; 5 37aadf42 6f54 df42 : svc #0x42 (offset 0xcc) | |||
RAM:00000000 ; 6 972df4b 12e4 df4b : svc #0x4b (offset 0xde) | |||
RAM:00000000 ; 7 2293df54 4526 df54 : svc #0x54 (offset 0xf0) | |||
RAM:00000000 ; 8 21fadf5d 43f4 df5d : svc #0x5d (offset 0x102) | |||
RAM:00000000 ; 9 bba2ac57 17744 ac57 : data | |||
RAM:00000000 ; 10 bbac3d19 17758 3d19 : data | |||
RAM:00000000 ; 11 1e952001 3d2a 2001 : movs r0, #0x01 | |||
RAM:00000000 ; | |||
RAM:00000000 ; ipatches (old): | |||
RAM:00000000 ; 0 b57df00 16ae df00 : svc #0x00 (offset 0x48) | RAM:00000000 ; 0 b57df00 16ae df00 : svc #0x00 (offset 0x48) | ||
RAM:00000000 ; 1 1820df22 3040 df22 : svc #0x22 (offset 0x8c) | RAM:00000000 ; 1 1820df22 3040 df22 : svc #0x22 (offset 0x8c) | ||
| Line 1,089: | Line 1,477: | ||
The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices. | The last 4 patches are exclusive to the Switch, while the remaining ones are often included in most Tegra210 based devices. | ||
==== | ==== IROM patch 0 ==== | ||
This patch configures clock enables and clock gate overrides for new hardware. | This patch configures clock enables and clock gate overrides for new hardware. | ||
| Line 1,138: | Line 1,526: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 1 ==== | ||
This patch is a bugfix. | This patch is a bugfix. | ||
| Line 1,150: | Line 1,538: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 2 ==== | ||
This patch adjusts USB configurations. | This patch adjusts USB configurations. | ||
| Line 1,166: | Line 1,554: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 3 ==== | ||
This patch ensures that waiting on PRC_PENDING from the XUSB_DEV register T_XUSB_DEV_XHCI_PORTSC never fails. | 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. | This patch allows backing up and restoring strapping options for warmboot. | ||
| Line 1,199: | Line 1,589: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 5 ==== | ||
This patch adjusts USB configurations. | This patch adjusts USB configurations. | ||
| Line 1,216: | Line 1,606: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 6 ==== | ||
This patch is a factory backdoor. | This patch is a factory backdoor. | ||
| Line 1,239: | Line 1,629: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 7 ==== | ||
This patch is a bugfix. | This patch is a bugfix. | ||
| Line 1,271: | Line 1,661: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patch 8 ==== | ||
This patch is a bugfix. | This patch is a bugfix. | ||
| Line 1,291: | Line 1,681: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== IROM patches 9 and 10 ==== | ||
These patches modify the 256-bit Secure Provisioning AES key with index 0x3A. | These patches modify the 256-bit Secure Provisioning AES key with index 0x3A. | ||
==== | ==== 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. | This patch forces the value of [[Security_Engine|SE_TZRAM_SECURITY]] to be 0x01 instead of restoring it from the saved SE context. | ||
| Line 1,339: | Line 1,729: | ||
| 1 | | 1 | ||
|- | |- | ||
| 7.0.0- | | 7.0.0-8.0.1 | ||
| 9 | | 9 | ||
| 1 | |||
|- | |||
| 8.1.0 | |||
| 10 | |||
| 1 | |||
|- | |||
| 9.0.0-9.0.1 | |||
| 11 | |||
| 1 | | 1 | ||
|} | |} | ||
| Line 1,346: | Line 1,744: | ||
If too many fuses are burnt the bootloader will panic immediately. | If too many fuses are burnt the bootloader will panic immediately. | ||
If too few are burnt, the bootloader will enable fuse programming and write the expected value to | If too few are burnt, the bootloader will enable fuse programming and write the expected value to fuses [[#reserved_odm6|reserved_odm6]] and [[#reserved_odm7|reserved_odm7]]. Afterwards, fuse programming is disabled and the panic value 0x21 is written to PMC_SCRATCH200 register (0x7000EC40). Finally, the watchdog timer is initialized and programmed to force a reset. | ||
On a subsequent boot, after the anti-downgrade fuses are checked again, the PMC_RST_STATUS register (0x7000E5B4) is checked and if set to 0x01 (watchdog reset) the PMC_SCRATCH200 register (0x7000EC40) will be checked for the panic value 0x21. | On a subsequent boot, after the anti-downgrade fuses are checked again, the PMC_RST_STATUS register (0x7000E5B4) is checked and if set to 0x01 (watchdog reset) the PMC_SCRATCH200 register (0x7000EC40) will be checked for the panic value 0x21. | ||
PMC_RST_STATUS will only be set back to 0 (power on reset) if the fuse count matches the new expected value, otherwise the system will panic. | PMC_RST_STATUS will only be set back to 0 (power on reset) if the fuse count matches the new expected value, otherwise the system will panic. | ||