Difference between revisions of "How to update OTP with U-Boot"
[quality revision] | [quality revision] |
m (→STM32MP15x support)
|
m (→Simple OTP examples)
|
Applicable for | STM32MP13x lines, STM32MP15x lines |
This page explains how to manually update OTP with the U-Boot fuse
command.
Contents
1 The fuse command[edit]
![]() |
Programming fuses is an irreversible operation!This may brick your system. Use this command only if you are sure of what you are doing! |
The fuse
command allows you to update the OTP words in U-Boot:
- sense/program to directly access the OTP value (for a permanent update)
- read/overidde override to access only the shadow cache value (for a temporary update).
STM32MP> help fuse fuse - Fuse sub-system Usage: fuse read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words, starting at 'word' fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words, starting at 'word' fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or several fuse words, starting at 'word' (PERMANENT) fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or several fuse words, starting at 'word'.
See doc/README.fuse for details.
2 STM32MP15x STM32MP support[edit]
The STM32MP15x lines support
fuse</code command is implemented in drivers/misc/stm32mp_fuse.c :
-
For the STM32MP15x lines
with 2 banks:
- <bank> = SOC OTP: 0
- #STM32MP1 OTP
- <bank> = PMIC NVM : 1 #STPMIC1 NVM
-
For the STM32MP13x lines
with 1 bank:
- <bank> = SOC OTP: 0 #STM32MP1 OTP
2.1 STM32MP15x STM32MP OTP[edit]
<bank> = 0 provides access to the 96 STM32MP13x or STM32MP15x OTP words with the BSEC driver: arch/arm/mach-stm32mp/bsec.c .
Refer to the STM32MP13 reference manuals or STM32MP15 reference manuals for the OTP layout.
The OTP<index> words value and lock status (0=unlocked, 1=locked) are available with <index> = 0 to 95 :
- for value: <word> = <index>
- for lock status: <word> = 0x10000000 + <index>
not shadowed, only support operation 'sense
' and 'program'.program
the status bit-field is same than STM32CubeProgrammer OTP management:- [0]: 1 bit read error detected: 1 = OTP value isn't valid
- [26]: 1 bit lock error
- [27]: 1 bit sticky programming lock
- [28]: 1 bit shadow write sticky lock
- [29]: 1 bit shadow read sticky lock
- [30]: 1 bit permanent write lock
Only 32 lower OTPs words are accessible by default, the software needs to manage exceptions to allow some upper OTPs to be accessed by the non-secure world as described in BSEC_device_tree_configuration.
2.1.1 Simple OTP examples[edit]
1) Read OTP value for OTP57 and 58 (2 OTP words)
STM32MP> fuse sense 0 57 2 Sensing bank 0: Word 0x00000039: 42e18000 0000e448
2) Check lock status of OTP 57 - 60 (4 words at index 57 = 0x39)
STM32MP> fuse sense 0 0x10000039 4 Sensing bank 0: Word 0x10000039: 0000000140000000 0000000140000000 0000000140000000 00000000
3) Display shadow values for all OTPs
When only the 32 lower OTPs are accessible:
STM32MP> fuse read 0 0 32 Reading bank 0: Word 0x00000000: 00000017 00008001 00000000 00000000 Word 0x00000004: 00000000 00000000 00000000 00000000 Word 0x00000008: 00000000 82004000 00000000 00000000 Word 0x0000000c: 7d04f0db 00470022 33385115 34383330 Word 0x00000010: 22986562 27010551 7a470140 06cc1608 Word 0x00000014: 5e560054 00000000 00000000 401a300c Word 0x00000018: ffffffff ffffffff ffffffff ffffffff Word 0x0000001c: ffffffff ffffffff ffffffff ffffffff
When all the 96 OTPs are available:
STM32MP> fuse read 0 0 96 Reading bank 0: Word 0x00000000: 00000017 00008000 00000000 00000000 Word 0x00000004: 00000000 00000000 00000000 00000000 Word 0x00000008: 00000000 00000000 00000000 00000000 Word 0x0000000c: 7cf5f0f9 00410032 33385116 34383330 Word 0x00000010: 129675aa 2931215e 7a550000 069013ec Word 0x00000014: 5e360042 00000000 00000000 40133023 Word 0x00000018: 00000000 00000000 00000000 00000000 Word 0x0000001c: 00000000 00000000 00000000 00000000 Word 0x00000020: 00000000 00000000 00000000 00000000 Word 0x00000024: 00000000 00000000 00000000 00000000 Word 0x00000028: aa333e40 b5e90dda f15f4678 8ab41400 Word 0x0000002c: b74efe3a f0a03b1b 01e016b3 d06a79dd Word 0x00000030: 48b96fbe 20fbd352 6732dbf4 edc395f9 Word 0x00000034: cdf15575 418fd3d0 0bb7d994 8dc929d0 Word 0x00000038: 00000000 42e18000 0000e448 12722301 Word 0x0000003c: 00000000 00000000 00000000 00000000 Word 0x00000040: 00000000 00000000 00000000 00000000 Word 0x00000044: 00000000 00000000 00000000 00000000 Word 0x00000048: 00000000 00000000 00000000 00000000 Word 0x0000004c: 00000000 00000000 00000000 00000000 Word 0x00000050: 00000000 00000000 00000000 00000000 Word 0x00000054: 00000000 00000000 00000000 00000000 Word 0x00000058: 00000000 00000000 00000000 00000000 Word 0x0000005c: 00000000 00000000 00000000 00000000
4) Override value for one OTP
STM32MP> fuse override 0 0x0000005c 1 Overriding bank 0 word 0x0000005c with 0x00000001... STM32MP> fuse read 0 0x0000005c Reading bank 0: Word 0x0000005c: 00000001 STM32MP> fuse sense 0 0x0000005c Sensing bank 0: Word 0x0000005c: 00000000
2.1.2 MAC address example for STM32MP15x[edit]
For STM32MP15_boards, the MAC address[1] is retrieved in the 2 OTP words:
- OTP_57[31:0] = MAC_ADDR[31:0]
- OTP_58[15:0] = MAC_ADDR[47:32]
To program a MAC address on virgin OTP words above, you can use the fuse
command on bank 0 to access internal OTP words and lock them:
Prerequisite: check if a MAC address isn't yet programmed in OTP.
1) Check OTPs: their value must be equal to 0:
STM32MP> fuse sense 0 57 2
Sensing bank 0:
Word 0x00000039: 00000000 00000000
2) Check environment variable:
STM32MP> env print ethaddr
## Error: "ethaddr" not defined
3) Check lock status of OTP 57 & 58 (at 0x39, 0=unlocked, 1=locked):
STM32MP> fuse sense 0 0x10000039 2
Sensing bank 0:
Word 0x10000039: 00000000 00000000
Example to set MAC address "12:34:56:78:9a:bc"
1) Write OTP:
STM32MP> fuse prog -y 0 57 0x78563412 0x0000bc9a
![]() |
This prog command cannot be executed twice because the values of these 2 upper OTP words are ECC-protected. To avoid an issue for a second operation these OTPs must be locked when programmed. |
2) Read OTP:
STM32MP> fuse sense 0 57 2
Sensing bank 0:
Word 0x00000039: 78563412 0000bc9a
3) Lock OTP:
STM32MP> fuse prog 0 0x10000039 10x40000000 10x40000000 STM32MP> fuse sense 0 0x10000039 2 Sensing bank 0: Word 0x10000039: 0000000140000000 0000000140000000
4) OTP is used after REBOOT, in the trace:
### Setting environment from OTP MAC address = "12:34:56:78:9a:bc"
5) Check env update:
STM32MP> env print ethaddr
ethaddr=12:34:56:78:9a:bc
2.1.3 MAC address example for STM32MP13x[edit]
For STM32MP13_boards, the two MAC address are retrieved in the 3 OTP words:
- OTP_57[31:0] = MAC_ADDR1[31:0]
- OTP_58[15:0] = MAC_ADDR1[47:32]
- OTP_58[31:16] = MAC_ADDR2[15:0]
- OTP_59[31:0] = MAC_ADDR2[47:16]
See the full sequence in previous chapter, with a added OTP, for example:
STM32MP> fuse prog -y 0 57 e17ae710 e71094a2 95a2e17a
STM32MP> fuse read 0 57 3 Reading bank 0: Word 0x00000039: e17ae710 e71094a2 95a2e17a
STM32MP> env print ... eth1addr=10:e7:7a:e1:a2:95 ethaddr=10:e7:7a:e1:a2:94 ...
2.2 STPMIC1 NVM[edit]
<bank> = 1 provides access to the non-volatile memory (NVM) of the PMIC on the board when PMIC is managed by U-Boot.
It is not the case in OpenSTLinux, when OP-TEE is used.
For STPMIC1, the NVM has 8 bytes as defined in datasheet: DS12792, with <word> = <0xf8> to <0xff>.
1) Read the values of the 8 NVM
STM32MP> fuse read 1 0xf8 8 Reading bank 1: Word 0x000000f8: 000000ee 00000092 000000c0 00000002 Word 0x000000fc: 000000f2 00000080 00000002 00000033
2) Read 2 NVM shadow values
STM32MP> fuse sense 1 0xf9 2 Sensing bank 1: Word 0x000000f9: 00000092 000000c0
3) Update the NVM at index 0xfc with value 0xf2
STM32MP> fuse prog 1 0xfc 0xf2 Programming bank 1 word 0x000000fc to 0x000000f2... Warning: Programming fuses is an irreversible operation! This may brick your system. Use this command only if you are sure of what you are doing! Really perform this fuse programming? <y/N> y
3 References[edit]
<noinclude>{{ApplicableFor |MPUs list=STM32MP13x, STM32MP15x |MPUs checklist=STM32MP13x,STM32MP15x }}</noinclude> This page explains how to manually update OTP with the [[U-Boot_overview|U-Boot]] <code>fuse</code> command. == The fuse command == {{Warning| Programming fuses is an irreversible operation!</br>This may brick your system. </br>Use this command only if you are sure of what you are doing!}} The <code>fuse</code> command allows you to update the OTP words in U-Boot: * {{Highlight|sense}}/{{Highlight|program}} to directly access the OTP value (for a permanent update) * {{Highlight|read}}/{{Highlight|overiddeoverride}} to access only the shadow cache value (for a temporary update). {{Board$U-Boot$}} help fuse fuse - Fuse sub-system Usage: fuse {{Highlight|read}} {{HighlightParam|<bank>}} {{HighlightParam|<word>}} [<cnt>] - read 1 or 'cnt' fuse words, starting at 'word' fuse {{Highlight|sense}} {{HighlightParam|<bank>}} {{HighlightParam|<word>}} [<cnt>] - sense 1 or 'cnt' fuse words, starting at 'word' fuse {{Highlight|prog}} [-y] {{HighlightParam|<bank>}} {{HighlightParam|<word>}} <hexval> [<hexval>...] - program 1 or several fuse words, starting at 'word' (PERMANENT) fuse {{Highlight|override}} {{HighlightParam|<bank>}} {{HighlightParam|<word>}} <hexval> [<hexval>...] - override 1 or several fuse words, starting at 'word'. See {{CodeSource | U-Boot | doc/README.fuse}} for details. == STM32MP15xSTM32MP support == The {{MicroprocessorDevice | device=15}} support <code>fuse</code command is implemented in {{CodeSource | U-Boot | drivers/misc/stm32mp_fuse.c}} with 2 banks: *: * For the {{MicroprocessorDevice | device=15}} with 2 banks: ** {{HighlightParam|<bank>}} = SOC OTP: {{HighlightParam|0}} [[#STM32MP15x#STM32MP1 OTP]] ** {{HighlightParam|<bank>}} = PMIC NVM : {{HighlightParam|1}} [[#STPMIC1 NVM]]. === STM32MP15x * For the {{MicroprocessorDevice | device=13}} with 1 bank: ** {{HighlightParam|<bank>}} = SOC OTP: {{HighlightParam|0}} [[#STM32MP1 OTP]] === STM32MP OTP === {{HighlightParam|<bank>}} = {{HighlightParam|0}} provides access to the 96 STM32MP13x or STM32MP15x OTP words with the BSEC driver: {{CodeSource | U-Boot | arch/arm/mach-stm32mp/bsec.c }}. Refer to the [[STM32MP13 resources#Reference manuals|STM32MP13 reference manuals]] or [[STM32MP15 resources#Reference manuals|STM32MP15 reference manuals]] for the OTP layout. The OTP{{Highlight|<index>}} words value and lock status (0=unlocked, 1=locked) are available with {{Highlight|<index>}} = {{Highlight|0}} to {{Highlight|95}} : * for value: {{HighlightParam|<word>}} = {{Highlight|<index>}} * for lock status: {{HighlightParam|<word>}} = 0x10000000 + {{Highlight|<index>}}<br/>not shadowed, only support operation '<code>sense'</code> and '<code>program'. </code><br/>the status bit-field is same than [[STM32CubeProgrammer OTP management]]: ** [0]: 1 bit read error detected: 1 = OTP value isn't valid ** [26]: 1 bit lock error ** [27]: 1 bit sticky programming lock ** [28]: 1 bit shadow write sticky lock ** [29]: 1 bit shadow read sticky lock ** [30]: 1 bit '''permanent write lock''' Only 32 lower OTPs words are accessible by default, the software needs to manage exceptions to allow some upper OTPs to be accessed by the non-secure world as described in [[BSEC_device_tree_configuration]]. ==== Simple OTP examples ==== 1) Read OTP value for OTP57 and 58 (2 OTP words) {{Board$U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 57 2 Sensing bank 0: Word 0x00000039: 42e18000 0000e448 2) Check lock status of OTP 57 - 60 (4 words at index 57 = 0x39) {{Board$U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 0x10000039 4 Sensing bank 0: Word 0x10000039: 00000001 00000001 0000000140000000 40000000 40000000 00000000 3) Display shadow values for all OTPs When only the 32 lower OTPs are accessible: {{Board$U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0 32 Reading bank 0: Word 0x00000000: 00000017 00008001 00000000 00000000 Word 0x00000004: 00000000 00000000 00000000 00000000 Word 0x00000008: 00000000 82004000 00000000 00000000 Word 0x0000000c: 7d04f0db 00470022 33385115 34383330 Word 0x00000010: 22986562 27010551 7a470140 06cc1608 Word 0x00000014: 5e560054 00000000 00000000 401a300c Word 0x00000018: ffffffff ffffffff ffffffff ffffffff Word 0x0000001c: ffffffff ffffffff ffffffff ffffffff When all the 96 OTPs are available: {{Board$U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0 96 Reading bank 0: Word 0x00000000: 00000017 00008000 00000000 00000000 Word 0x00000004: 00000000 00000000 00000000 00000000 Word 0x00000008: 00000000 00000000 00000000 00000000 Word 0x0000000c: 7cf5f0f9 00410032 33385116 34383330 Word 0x00000010: 129675aa 2931215e 7a550000 069013ec Word 0x00000014: 5e360042 00000000 00000000 40133023 Word 0x00000018: 00000000 00000000 00000000 00000000 Word 0x0000001c: 00000000 00000000 00000000 00000000 Word 0x00000020: 00000000 00000000 00000000 00000000 Word 0x00000024: 00000000 00000000 00000000 00000000 Word 0x00000028: aa333e40 b5e90dda f15f4678 8ab41400 Word 0x0000002c: b74efe3a f0a03b1b 01e016b3 d06a79dd Word 0x00000030: 48b96fbe 20fbd352 6732dbf4 edc395f9 Word 0x00000034: cdf15575 418fd3d0 0bb7d994 8dc929d0 Word 0x00000038: 00000000 42e18000 0000e448 12722301 Word 0x0000003c: 00000000 00000000 00000000 00000000 Word 0x00000040: 00000000 00000000 00000000 00000000 Word 0x00000044: 00000000 00000000 00000000 00000000 Word 0x00000048: 00000000 00000000 00000000 00000000 Word 0x0000004c: 00000000 00000000 00000000 00000000 Word 0x00000050: 00000000 00000000 00000000 00000000 Word 0x00000054: 00000000 00000000 00000000 00000000 Word 0x00000058: 00000000 00000000 00000000 00000000 Word 0x0000005c: 00000000 00000000 00000000 00000000 4) Override value for one OTP {{Board$U-Boot$}} fuse {{Highlight|override}} {{HighlightParam|0}} 0x0000005c 1 Overriding bank 0 word 0x0000005c with 0x00000001... {{Board$ {{U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0x0000005c Reading bank 0: Word 0x0000005c: 00000001 {{Board$U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 0x0000005c Sensing bank 0: Word 0x0000005c: 00000000 ==== MAC address example for STM32MP15x ==== For [[STM32MP15_boards]], the MAC address<ref>https://en.wikipedia.org/wiki/MAC_address</ref> is retrieved in the 2 OTP words: * OTP_57[31:0] = MAC_ADDR[31:0] * OTP_58[15:0] = MAC_ADDR[47:32] To program a MAC address on virgin OTP words above, you can use the <code>fuse</code> command on bank 0 to access internal OTP words and lock them: Prerequisite: check if a MAC address isn't yet programmed in OTP. 1) Check OTPs: their value must be equal to 0: {{Board$U-Boot$}} fuse sense 0 57 2 Sensing bank 0: Word 0x00000039: 00000000 00000000 2) Check environment variable: {{Board$U-Boot$}} env print ethaddr ## Error: "ethaddr" not defined 3) Check lock status of OTP 57 & 58 (at 0x39, 0=unlocked, 1=locked): {{Board$U-Boot$}} fuse sense 0 0x10000039 2 Sensing bank 0: Word 0x10000039: 00000000 00000000 Example to set MAC address "12:34:56:78:9a:bc" 1) Write OTP: {{Board$U-Boot$}} fuse prog -y 0 57 0x78563412 0x0000bc9a {{Warning|This prog command cannot be executed twice because the values of these 2 upper OTP words are ECC-protected.<br/>To avoid an issue for a second operation these OTPs must be locked when programmed.}} 2) Read OTP: {{Board$U-Boot$}} fuse sense 0 57 2 Sensing bank 0: Word 0x00000039: 78563412 0000bc9a 3) Lock OTP: {{Board$U-Boot$}} fuse prog 0 0x10000039 1 1 {{Board$0x40000000 0x40000000 {{U-Boot$}} fuse sense 0 0x10000039 2 Sensing bank 0: Word 0x10000039: 00000001 0000000140000000 40000000 4) OTP is used after REBOOT, in the trace: ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc" 5) Check env update: {{Board$U-Boot$}} env print ethaddr ethaddr=12:34:56:78:9a:bc === = MAC address example for STM32MP13x ==== For [[STM32MP13_boards]], the two MAC address are retrieved in the 3 OTP words: * OTP_57[31:0] = MAC_ADDR1[31:0] * OTP_58[15:0] = MAC_ADDR1[47:32] * OTP_58[31:16] = MAC_ADDR2[15:0] * OTP_59[31:0] = MAC_ADDR2[47:16] See the full sequence in previous chapter, with a added OTP, for example: {{U-Boot$}} fuse prog -y 0 57 {{Highlight|e17ae710}} {{HighlightParam|e710}}{{Highlight|94a2}} {{HighlightParam|95a2e17a}} {{U-Boot$}} fuse read 0 57 3 Reading bank 0: Word 0x00000039: {{Highlight|e17ae710}} {{HighlightParam|e710}}{{Highlight|94a2}} {{HighlightParam|95a2e17a}} {{U-Boot$}} env print ... eth1addr={{HighlightParam|10:e7:7a:e1:a2:95}} ethaddr={{Highlight|10:e7:7a:e1:a2:94}} ... === STPMIC1 NVM === {{HighlightParam|<bank>}} = {{HighlightParam|1}} provides access to the non-volatile memory (NVM) of the PMIC on the board. when PMIC is managed by U-Boot. It is not the case in OpenSTLinux, when OP-TEE is used. For [[PMIC hardware components#STPMIC1|STPMIC1]], the NVM has 8 bytes as defined in datasheet: [[STM32MP15 resources#DS12792|DS12792]], with {{HighlightParam|<word>}} = {{HighlightParam|<0xf8>}} to {{HighlightParam|<0xff>}}. 1) Read the values of the {{HighlightParam|8}} NVM {{Board$U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|1}} {{HighlightParam|0xf8}} {{HighlightParam|8}} Reading bank 1: Word 0x000000f8: 000000ee 00000092 000000c0 00000002 Word 0x000000fc: 000000f2 00000080 00000002 00000033 2) Read {{HighlightParam|2}} NVM shadow values {{Board$U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|1}} {{HighlightParam|0xf9}} {{HighlightParam|2}} Sensing bank 1: Word 0x000000f9: 00000092 000000c0 3) Update the NVM at index {{HighlightParam|0xfc}} with value {{Highlight|0xf2}} {{Board$U-Boot$}} fuse {{Highlight|prog}} {{HighlightParam|1}} {{HighlightParam|0xfc}} {{Highlight|0xf2}} Programming bank 1 word 0x000000fc to 0x000000f2... Warning: Programming fuses is an irreversible operation! This may brick your system. Use this command only if you are sure of what you are doing! Really perform this fuse programming? <y/N> y ==References==<references /> <noinclude> {{PublicationRequestId | 16217| 2020-05-26 | }} [[Category:How to populate boards]] [[Category:U-Boot|U-Boot - 9]]</noinclude>
(21 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
+ | <noinclude>{{ApplicableFor |
||
+ | |MPUs list=STM32MP13x, STM32MP15x |
||
+ | |MPUs checklist=STM32MP13x,STM32MP15x |
||
+ | }}</noinclude> |
||
This page explains how to manually update OTP with the [[U-Boot_overview|U-Boot]] <code>fuse</code> command. |
This page explains how to manually update OTP with the [[U-Boot_overview|U-Boot]] <code>fuse</code> command. |
||
Line 7: | Line 11: | ||
The <code>fuse</code> command allows you to update the OTP words in U-Boot: |
The <code>fuse</code> command allows you to update the OTP words in U-Boot: |
||
* {{Highlight|sense}}/{{Highlight|program}} to directly access the OTP value (for a permanent update) |
* {{Highlight|sense}}/{{Highlight|program}} to directly access the OTP value (for a permanent update) |
||
− | * {{Highlight|read}}/{{Highlight| |
+ | * {{Highlight|read}}/{{Highlight|override}} to access only the shadow cache value (for a temporary update). |
− | {{ |
+ | {{U-Boot$}} help fuse |
fuse - Fuse sub-system |
fuse - Fuse sub-system |
||
Line 24: | Line 28: | ||
See {{CodeSource | U-Boot | doc/README.fuse}} for details. |
See {{CodeSource | U-Boot | doc/README.fuse}} for details. |
||
− | == |
+ | == STM32MP support == |
− | The |
+ | The <code>fuse</code command is implemented in {{CodeSource | U-Boot | drivers/misc/stm32mp_fuse.c}}:
|
− | * {{HighlightParam|<bank>}} = SOC OTP: {{HighlightParam|0}} [[# |
+ |
* For the {{MicroprocessorDevice | device=15}} with 2 banks: |
− | * {{HighlightParam|<bank>}} = PMIC NVM : {{HighlightParam|1}} [[#STPMIC1 NVM]] |
+ |
** {{HighlightParam|<bank>}} = SOC OTP: {{HighlightParam|0}} [[#STM32MP1 OTP]] |
+ |
** {{HighlightParam|<bank>}} = PMIC NVM : {{HighlightParam|1}} [[#STPMIC1 NVM]] |
||
+ | * For the {{MicroprocessorDevice | device=13}} with 1 bank: |
||
+ | ** {{HighlightParam|<bank>}} = SOC OTP: {{HighlightParam|0}} [[#STM32MP1 OTP]] |
||
− | === |
+ | === STM32MP OTP === |
− | {{HighlightParam|<bank>}} = {{HighlightParam|0}} provides access to the 96 STM32MP15x OTP words with the BSEC driver: {{CodeSource | U-Boot | arch/arm/mach-stm32mp/bsec.c }}. |
+ | {{HighlightParam|<bank>}} = {{HighlightParam|0}} provides access to the 96 STM32MP13x or STM32MP15x OTP words with the BSEC driver: {{CodeSource | U-Boot | arch/arm/mach-stm32mp/bsec.c }}. |
− | Refer to the [[STM32MP15 resources#Reference manuals|STM32MP15 reference manuals]] for the OTP layout. |
+ | Refer to the [[STM32MP13 resources#Reference manuals|STM32MP13 reference manuals]] or [[STM32MP15 resources#Reference manuals|STM32MP15 reference manuals]] for the OTP layout. |
The OTP{{Highlight|<index>}} words value and lock status (0=unlocked, 1=locked) are available with {{Highlight|<index>}} = {{Highlight|0}} to {{Highlight|95}} : |
The OTP{{Highlight|<index>}} words value and lock status (0=unlocked, 1=locked) are available with {{Highlight|<index>}} = {{Highlight|0}} to {{Highlight|95}} : |
||
* for value: {{HighlightParam|<word>}} = {{Highlight|<index>}} |
* for value: {{HighlightParam|<word>}} = {{Highlight|<index>}} |
||
− | * for lock status: {{HighlightParam|<word>}} = 0x10000000 + {{Highlight|<index>}}<br/>not shadowed, only support operation ' |
+ | * for lock status: {{HighlightParam|<word>}} = 0x10000000 + {{Highlight|<index>}}<br/>not shadowed, only support operation <code>sense</code> and <code>program</code><br/>the status bit-field is same than [[STM32CubeProgrammer OTP management]]:
|
+ |
** [0]: 1 bit read error detected: 1 = OTP value isn't valid
|
||
+ | ** [26]: 1 bit lock error |
||
+ | ** [27]: 1 bit sticky programming lock |
||
+ | ** [28]: 1 bit shadow write sticky lock |
||
+ | ** [29]: 1 bit shadow read sticky lock |
||
+ |
** [30]: 1 bit '''permanent write lock''' |
||
Only 32 lower OTPs words are accessible by default, the software needs to manage exceptions to allow some upper OTPs to be accessed by the non-secure world as described in [[BSEC_device_tree_configuration]]. |
Only 32 lower OTPs words are accessible by default, the software needs to manage exceptions to allow some upper OTPs to be accessed by the non-secure world as described in [[BSEC_device_tree_configuration]]. |
||
Line 43: | Line 56: | ||
1) Read OTP value for OTP57 and 58 (2 OTP words) |
1) Read OTP value for OTP57 and 58 (2 OTP words) |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 57 2 |
Sensing bank 0: |
Sensing bank 0: |
||
Line 50: | Line 63: | ||
2) Check lock status of OTP 57 - 60 (4 words at index 57 = 0x39) |
2) Check lock status of OTP 57 - 60 (4 words at index 57 = 0x39) |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 0x10000039 4 |
Sensing bank 0: |
Sensing bank 0: |
||
− | Word 0x10000039: |
+ | Word 0x10000039: 40000000 40000000 40000000 00000000 |
3) Display shadow values for all OTPs |
3) Display shadow values for all OTPs |
||
Line 59: | Line 72: | ||
When only the 32 lower OTPs are accessible: |
When only the 32 lower OTPs are accessible: |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0 32 |
Reading bank 0: |
Reading bank 0: |
||
Line 73: | Line 86: | ||
When all the 96 OTPs are available: |
When all the 96 OTPs are available: |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0 96 |
Reading bank 0: |
Reading bank 0: |
||
Line 103: | Line 116: | ||
4) Override value for one OTP |
4) Override value for one OTP |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|override}} {{HighlightParam|0}} 0x0000005c 1 |
Overriding bank 0 word 0x0000005c with 0x00000001... |
Overriding bank 0 word 0x0000005c with 0x00000001... |
||
− | + | ||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|0}} 0x0000005c |
Reading bank 0: |
Reading bank 0: |
||
Word 0x0000005c: 00000001 |
Word 0x0000005c: 00000001 |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|0}} 0x0000005c |
Sensing bank 0: |
Sensing bank 0: |
||
Word 0x0000005c: 00000000 |
Word 0x0000005c: 00000000 |
||
− | ==== MAC address example ==== |
+ | ==== MAC address example for STM32MP15x ==== |
For [[STM32MP15_boards]], the MAC address<ref>https://en.wikipedia.org/wiki/MAC_address</ref> is retrieved in the 2 OTP words: |
For [[STM32MP15_boards]], the MAC address<ref>https://en.wikipedia.org/wiki/MAC_address</ref> is retrieved in the 2 OTP words: |
||
* OTP_57[31:0] = MAC_ADDR[31:0] |
* OTP_57[31:0] = MAC_ADDR[31:0] |
||
Line 127: | Line 140: | ||
1) Check OTPs: their value must be equal to 0: |
1) Check OTPs: their value must be equal to 0: |
||
− | {{ |
+ | {{U-Boot$}} fuse sense 0 57 2 |
Sensing bank 0: |
Sensing bank 0: |
||
Word 0x00000039: 00000000 00000000 |
Word 0x00000039: 00000000 00000000 |
||
Line 133: | Line 146: | ||
2) Check environment variable: |
2) Check environment variable: |
||
− | {{ |
+ | {{U-Boot$}} env print ethaddr |
## Error: "ethaddr" not defined |
## Error: "ethaddr" not defined |
||
3) Check lock status of OTP 57 & 58 (at 0x39, 0=unlocked, 1=locked): |
3) Check lock status of OTP 57 & 58 (at 0x39, 0=unlocked, 1=locked): |
||
− | {{ |
+ | {{U-Boot$}} fuse sense 0 0x10000039 2 |
Sensing bank 0: |
Sensing bank 0: |
||
Word 0x10000039: 00000000 00000000 |
Word 0x10000039: 00000000 00000000 |
||
Line 146: | Line 159: | ||
1) Write OTP: |
1) Write OTP: |
||
− | {{ |
+ | {{U-Boot$}} fuse prog -y 0 57 0x78563412 0x0000bc9a |
{{Warning|This prog command cannot be executed twice because the values of these 2 upper OTP words are ECC-protected.<br/>To avoid an issue for a second operation these OTPs must be locked when programmed.}} |
{{Warning|This prog command cannot be executed twice because the values of these 2 upper OTP words are ECC-protected.<br/>To avoid an issue for a second operation these OTPs must be locked when programmed.}} |
||
Line 152: | Line 165: | ||
2) Read OTP: |
2) Read OTP: |
||
− | {{ |
+ | {{U-Boot$}} fuse sense 0 57 2 |
Sensing bank 0: |
Sensing bank 0: |
||
Word 0x00000039: 78563412 0000bc9a |
Word 0x00000039: 78563412 0000bc9a |
||
Line 158: | Line 171: | ||
3) Lock OTP: |
3) Lock OTP: |
||
− | {{ |
+ | {{U-Boot$}} fuse prog 0 0x10000039 0x40000000 0x40000000
|
− | {{ |
+ | {{U-Boot$}} fuse sense 0 0x10000039 2 |
Sensing bank 0: |
Sensing bank 0: |
||
− | Word 0x10000039: |
+ | Word 0x10000039: 40000000 40000000
|
4) OTP is used after REBOOT, in the trace: |
4) OTP is used after REBOOT, in the trace: |
||
Line 170: | Line 183: | ||
5) Check env update: |
5) Check env update: |
||
− | {{ |
+ | {{U-Boot$}} env print ethaddr |
ethaddr=12:34:56:78:9a:bc |
ethaddr=12:34:56:78:9a:bc |
||
+ | |||
+ | ==== MAC address example for STM32MP13x ==== |
||
+ | |||
+ | For [[STM32MP13_boards]], the two MAC address are retrieved in the 3 OTP words: |
||
+ | * OTP_57[31:0] = MAC_ADDR1[31:0] |
||
+ | * OTP_58[15:0] = MAC_ADDR1[47:32] |
||
+ | * OTP_58[31:16] = MAC_ADDR2[15:0] |
||
+ | * OTP_59[31:0] = MAC_ADDR2[47:16] |
||
+ | |||
+ | See the full sequence in previous chapter, with a added OTP, for example: |
||
+ | |||
+ | {{U-Boot$}} fuse prog -y 0 57 {{Highlight|e17ae710}} {{HighlightParam|e710}}{{Highlight|94a2}} {{HighlightParam|95a2e17a}} |
||
+ | |||
+ | {{U-Boot$}} fuse read 0 57 3 |
||
+ | Reading bank 0: |
||
+ | |||
+ | Word 0x00000039: {{Highlight|e17ae710}} {{HighlightParam|e710}}{{Highlight|94a2}} {{HighlightParam|95a2e17a}} |
||
+ | |||
+ | {{U-Boot$}} env print |
||
+ | ... |
||
+ | eth1addr={{HighlightParam|10:e7:7a:e1:a2:95}} |
||
+ | ethaddr={{Highlight|10:e7:7a:e1:a2:94}} |
||
+ | ... |
||
=== STPMIC1 NVM === |
=== STPMIC1 NVM === |
||
− | {{HighlightParam|<bank>}} = {{HighlightParam|1}} provides access to the non-volatile memory (NVM) of the PMIC on the board. |
+ | {{HighlightParam|<bank>}} = {{HighlightParam|1}} provides access to the non-volatile memory (NVM) of the PMIC on the board when PMIC is managed by U-Boot.
|
+ | |||
+ |
It is not the case in OpenSTLinux, when OP-TEE is used. |
||
For [[PMIC hardware components#STPMIC1|STPMIC1]], the NVM has 8 bytes as defined in datasheet: [[STM32MP15 resources#DS12792|DS12792]], with {{HighlightParam|<word>}} = {{HighlightParam|<0xf8>}} to {{HighlightParam|<0xff>}}. |
For [[PMIC hardware components#STPMIC1|STPMIC1]], the NVM has 8 bytes as defined in datasheet: [[STM32MP15 resources#DS12792|DS12792]], with {{HighlightParam|<word>}} = {{HighlightParam|<0xf8>}} to {{HighlightParam|<0xff>}}. |
||
Line 180: | Line 218: | ||
1) Read the values of the {{HighlightParam|8}} NVM |
1) Read the values of the {{HighlightParam|8}} NVM |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|read}} {{HighlightParam|1}} {{HighlightParam|0xf8}} {{HighlightParam|8}} |
Reading bank 1: |
Reading bank 1: |
||
Line 188: | Line 226: | ||
2) Read {{HighlightParam|2}} NVM shadow values |
2) Read {{HighlightParam|2}} NVM shadow values |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|sense}} {{HighlightParam|1}} {{HighlightParam|0xf9}} {{HighlightParam|2}} |
Sensing bank 1: |
Sensing bank 1: |
||
Line 195: | Line 233: | ||
3) Update the NVM at index {{HighlightParam|0xfc}} with value {{Highlight|0xf2}} |
3) Update the NVM at index {{HighlightParam|0xfc}} with value {{Highlight|0xf2}} |
||
− | {{ |
+ | {{U-Boot$}} fuse {{Highlight|prog}} {{HighlightParam|1}} {{HighlightParam|0xfc}} {{Highlight|0xf2}} |
Programming bank 1 word 0x000000fc to 0x000000f2... |
Programming bank 1 word 0x000000fc to 0x000000f2... |
||
Warning: Programming fuses is an irreversible operation! |
Warning: Programming fuses is an irreversible operation! |
||
Line 210: | Line 248: | ||
{{PublicationRequestId | 16217| 2020-05-26 | }} |
{{PublicationRequestId | 16217| 2020-05-26 | }} |
||
[[Category:How to populate boards]] |
[[Category:How to populate boards]] |
||
− | [[Category:U-Boot]] |
+ | [[Category:U-Boot|U-Boot - 9]] |
</noinclude> |
</noinclude> |