Difference between revisions of "NVMEM overview"
[quality revision] | [quality revision] |
m
|
m
|
Applicable for | STM32MP13x lines, STM32MP15x lines |
This article introduces how the NVMEM Linux® framework manages BSEC OTP data and how to read/write from/to it.
Contents
1 Framework purpose[edit]
The NVMEM Linux® framework provides a generic interface for the device non-volatile memory data devices such as:
- OTP (one-time programmable) fuses
- EEPROM
It offers kernel space and user space interfaces to read and/or write data such as analog calibration data or MAC address.
2 System overview[edit]

2.1 Component description[edit]
- NVMEM user (user space)
The user can use the NVMEM sysfs interface , from a user terminal or a custom application , to read/write data from/to NVMEM device(s) devices, and from user space.
- NVMEM user (kernel space)
User drivers can use The 'foo_driver' could be any driver in kernel space that uses the NVMEM API to read/write data from/to NVMEM device(s) from kernel space (devices (such as the analog calibration data used by an ADC driver).
- NVMEM framework (kernel space)
The NVMEM core provides sysfs interface and NVMEM API. They can be used to implement NVMEM user and NVMEM controller drivers.
- NVMEM drivers (kernel space)
Provider drivers such as STM32 ROMEM Linux® driver that exposes BSEC OTP data to the core.
- TEE framework (kernel space)
The TEE framework provides TEE client API to communicate with secure services, as the services provided by the OP-TEE Linux® driver.
- OP-TEE (Secure)
The OP-TEE secure OS is running on the Cortex-A in secure mode and exposes secure service with Trusted Applications (TA), as BSEC PTA .
- NVMEM hardware
NVMEM controller(s) controllers such as the BSEC internal peripheral[1]
2.2 API description[edit]
The NVMEM kernel documentation[2] describes:
- Kernel space API for NVMEM providers and NVMEM consumers.
- Userspace User space binary interface (sysfs).
See also sysfs-bus-nvmem[3] ABI documentation.
3 Configuration[edit]
3.1 Kernel configuration[edit]
Activate NVMEM framework in the kernel configuration through the Linux® menuconfig tool , (see Menuconfig or how to configure kernel () with CONFIG_NVMEM = y):
Device Drivers ---> [*] NVMEM Support ---> <*> STMicroelectronics STM32 factory-programmed memory support
3.2 Device tree configuration[edit]
The NVMEM data device tree bindings describe:
The BSEC internal peripheral[1] device tree bindings are explained described in the BSEC device tree configuration article.
4 How to use the framework[edit]
4.1 How to use NVMEM with sysfs interface[edit]
4.1.1 How to list NVMEM devices[edit]
The available NVMEM devices can be listed in sysfs directory /sys/bus/nvmem/devices.
Example to list of listing nvmem devices: BSEC is stm32-romem0
ls /sys/bus/nvmem/devices/ stm32-romem0
4.1.2 How to read OTPs OTP areas using NVMEM[edit]
Userspace The user space can read/write the raw NVMEM file located at : /sys/bus/nvmem/devices/*/nvmem.
For BSEC, the NVEM is the stm32-romem0 device, the . The content of non-secure OTPsOTP areas can be read but the secured OTPsOTP areas are masked, theirs and their values are replaced by 0.
Normally only the 32 lower OTPs OTP data can be accessed and , the upper OTPS is OTP data being restricted to security. If the user needs more than the 32 lower OTPs, there is OTP data, this can be managed by an exception management explained described in BSEC device tree configuration.
- Example to read of reading all nvmem data content on stm32-romem0 devices
dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem of=/tmp/file
- Example to display of displaying all nvmem data content
hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem
![]() |
A dedicated page describe describes the OTP area mapping for STM32MP13 and STM32MP15. |
4.1.3 How to write BSEC OTPs OTP data using NVMEM[edit]
![]() |
The below examples show how to write data to an NVMEM device. This may cause unrecoverable damage to the STM32 device (for example when writing to an OTP area) |
The BSEC OTP areas can be written by 32-bit word starting at OTP N, as follows:
# write OTP N word by word dd if=/tmp/file of=/sys/bus/nvmem/devices/stm32-romem0/nvmem bs=4 seek=N
or
# write OTP N, all the file in one request dd if=/tmp/file of=/sys/bus/nvmem/devices/stm32-romem0/nvmem seek=4*N oflag=seek_bytes
With a file /tmp/file containing the OTP data to write, its size is 32-bit word aligned; , for example:
# Create a 4 bytes length file filled with ones, e.g. 0xffffffff) dd if=/dev/zero count=1 bs=4 | tr '\000' '\377' > file # Create a 4 bytes length file, here 0x00000001 to update one OTP echo -n -e '\x01\x00\x00\x00' > /tmp/file # Create a 8 bytes length file, here 0x67452301 0xEFCDAB89 to update two OTPs echo -n -e '\x01\x23\x45\x67\x89\xAB\xCD\xEF' > /tmp/file
A lower OTP area can be written several time times for a bit per bit update if it is not locked.
An upper OTP data area can be written only if it is allowed in secure world device tree, and only one time; when once. When the upper OTP is written, it is permanent locked at the end of the NVMEM request to an avoid ECC issue on the second update. For the first example with bs = 4, this lock is performed after each OTP update and , while for the second example with oflag = seek_bytes the lock , it is done when all the OTPs OTP data in the input file are updated.
The full example to write Below a compete example of writing the upper OTP 60 is:
echo -n -e '\x01\x23\x45\x67' > /tmp/file hexdump -C /tmp/file 00000000 01 23 45 67 |.#Eg| 00000004 dd if=/tmp/file of=/sys/bus/nvmem/devices/stm32-romem0/nvmem bs=4 seek=60 reboot << >> hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem .... 000000f0 01 23 45 67 00 00 00 00 00 00 00 00 00 00 00 00 |.#Eg............| ....
The associated output in STM32CubeProgrammer is:
OTP REGISTERS: --------------------------------------------------------------------------- ID | value | status --------------------------------------------------------------------------- ... 060 | 0x67452301 | 0x40000000 |_[30] Permanent write lock
or in U-Boot
> fuse read 0 0 96 ... Word 0x0000003c: 67452301 00000000 00000000 00000000 ...
5 How to trace and debug the framework[edit]
5.1 How to trace[edit]
Ftrace can be used to trace the NVMEM framework:
cd /sys/kernel/debug/tracing cat available_filter_functions | grep nvmem # Show available filter functions rtc_nvmem_register rtc_nvmem_unregister nvmem_reg_read bin_attr_nvmem_read ...
Enable the kernel function tracer, then start using nvmem and display the result:
echo function > current_tracer echo "*nvmem*" > set_ftrace_filter # Trace all nvmem filter functions echo 1 > tracing_on # start ftrace hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem # dump nvmem 00000000 17 00 00 00 01 80 00 00 00 00 00 00 00 00 00 00 |................| ... echo 0 > tracing_on # stop ftrace cat trace # tracer: function # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | hexdump-478 [000] .... 423.502278: bin_attr_nvmem_read <-sysfs_kf_bin_read hexdump-478 [000] .... 423.502290: nvmem_reg_read <-bin_attr_nvmem_read hexdump-478 [000] .... 423.515804: bin_attr_nvmem_read <-sysfs_kf_bin_read
6 References[edit]
- ↑ 1.01.1 BSEC internal peripheral
- ↑ Documentation/driver-api/nvmem.rst , NVMEM subsytem kernel documentation
- ↑ Documentation/ABI/stable/sysfs-bus-nvmem , NVMEM ABI documentation
- ↑ Documentation/devicetree/bindings/nvmem/nvmem.yaml , NVMEM device tree bindings
- ↑ Documentation/devicetree/bindings/nvmem/nvmem-consumer.yaml , NVMEM consumer device tree bindings
<noinclude>{{ApplicableFor |MPUs list=STM32MP13x, STM32MP15x |MPUs checklist=STM32MP13x,STM32MP15x }}</noinclude> {{ReviewsComments|-- [[User:Nathalie Sangouard|Nathalie Sangouard]] ([[User talk:Nathalie Sangouard|talk]]) 15:46, 21 November 2022 (CET)<br />As the article has been set un approved by EX the 21/11/2022, if we want to have it for Wednesday, I need to cancel the TW review and start the Maintainer review. After the approval on wednesday, a TW Review must be launched}} This article introduces how the NVMEM Linux<sup>®</sup> framework manages BSEC OTP data and how to read/write from/to it.<p> ==Framework purpose== The NVMEM Linux<sup>®</sup> framework provides a generic interface for the device '''non-volatile memory data''' devices such as: * OTP (one-time programmable) fuses * EEPROM It offers kernel space and user space interfaces to read and/or /write data such as analog calibration data or MAC address. ==System overview== {{ ImageMap|Image:NVMEM_overview.png {{!}} thumb {{!}} 800px {{!}} center{{!}} rect 470 142 599 173 [[NVMEM_overview#API description|NVMEM sysfs interface]] rect 601 233 749 267 [[NVMEM_overview#API description|NVMEM consumers interface]] rect 480 660 600 700 [[BSEC internal peripheral]] rect 480 536 601 577 [[OP-TEE OTP PTA overview|BSEC PTA ]] rect 232 532 320 570 [[OP-TEE_overview|OP-TEE]] rect 479 453 600 492 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]] rect 522 412 612 445 [[OP-TEE_overview#TEE_Client_API|TEE Client API]] }} ===Component description=== * '''NVMEM user''' (user space) The user can use the NVMEM sysfs interface, from a user terminal or a custom application, to read/write data from/to NVMEM device(s) devices, and from user space. * '''NVMEM user''' (kernel space)User drivers can use The 'foo_driver' could be any driver in kernel space that uses the NVMEM API to read/write data from/to NVMEM device(s) from kernel space devices (such as the analog calibration data used by an ADC driver). * '''NVMEM framework''' (kernel space) The NVMEM core provides sysfs interface and NVMEM API. They can be used to implement NVMEM user and NVMEM controller drivers. * '''NVMEM drivers''' (kernel space) Provider drivers such as STM32 ROMEM Linux<sup>®</sup> driver that exposes BSEC OTP data to the core. * '''TEE framework''' (kernel space) The TEE framework provides [[OP-TEE_overview#TEE_Client_API|TEE client API]] to communicate with secure services, as the services provided by the OP-TEE Linux<sup>®</sup> driver. * ''' OP-TEE''' (Secure) The [[OP-TEE overview|'''OP-TEE secure OS''']] is running on the Cortex-A in [[Security_overview|secure mode]] and exposes secure service with '''Trusted Applications (TA)''', as [[OP-TEE OTP PTA overview|BSEC PTA ]]. * '''NVMEM hardware''' NVMEM controller(s)controllers such as the ''BSEC internal peripheral''<ref name="BSEC internal peripheral">[[BSEC internal peripheral]]</ref> ===API description=== The NVMEM kernel documentation<ref name="documentation_nvmem">{{CodeSource | Linux kernel | Documentation/driver-api/nvmem.rst}}, NVMEM subsytem kernel documentation</ref> describes: * Kernel space API for NVMEM '''providers''' and NVMEM '''consumers'''. * Userspace User space binary interface (sysfs). See also ''sysfs-bus-nvmem''<ref name="nvmem_abi">{{CodeSource | Linux kernel | Documentation/ABI/stable/sysfs-bus-nvmem}}, NVMEM ABI documentation</ref> ABI documentation. ==Configuration== ===Kernel configuration=== Activate NVMEM framework in the kernel configuration through the Linux<sup>®</sup> menuconfig tool, (see [[Menuconfig or how to configure kernel | Menuconfig or how to configure kernel ]] (CONFIG_NVMEM=y)]]) with CONFIG_NVMEM = y: Device Drivers ---> [*] NVMEM Support ---><*> STMicroelectronics STM32 factory-programmed memory support ===Device tree configuration=== The NVMEM data device tree bindings describe: * The location of non-volatile memory data * The NVMEM data providers<ref name="nvmem dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem.yaml}}, NVMEM device tree bindings</ref> * The NVMEM data consumers<ref name="nvmem-consumer dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem-consumer.yaml}}, NVMEM consumer device tree bindings</ref> The ''BSEC internal peripheral''<ref name="BSEC internal peripheral"/> device tree bindings are explaineddescribed in the [[BSEC device tree configuration]] article. ==How to use the framework== ===How to use NVMEM with sysfs interface=== ====How to list NVMEM devices==== The available NVMEM devices can be listed in sysfs directory {{Highlight|/sys/bus/nvmem/devices}}. Example to '''list''' nvmem devices: of '''listing''' nvmem devices: BSEC is '''stm32-romem0''' {{Board$}} ls /sys/bus/nvmem/devices/ stm32-romem0 ====How to read OTPs OTP areas using NVMEM==== Userspace The user space can read/write the raw NVMEM file located at: {{Highlight|/sys/bus/nvmem/devices/*/nvmem}}. For BSEC, the NVEM is the '''stm32-romem0''' device, the. The content of '''non-secure OTPsOTP areas''' can be read but the '''secured OTPsOTP areas''' are masked, theirs and their values are replaced by 0. Normally only the 32 lower OTPs OTP data can be accessed and , the upper OTPS is OTP data being restricted to security. If the user needs more than the 32 lower OTPs, there is an exception management explained OTP data, this can be managed by an exception described in [[BSEC device tree configuration]]. * Example to '''readof '''reading''' all nvmem data content on stm32-romem0 devices {{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem of=/tmp/file * Example to '''display''' nvmem data contentof '''displaying''' all nvmem data{{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem {{Info|A dedicated page describedescribes the OTP area mapping for [[STM32MP15_OTP_mapping|STM32MP13]] and [[STM32MP15_OTP_mapping|STM32MP15]].}} ====How to write BSEC OTPs OTP data using NVMEM==== {{Warning|The below examples show how to write data to an NVMEM device. This may cause unrecoverable damage to the STM32 device (for example when writing to an OTP area)}} {{Info| Note that lower BSEC OTPs OTP areas are using 2:1 redundancy, so they can be written bit per bit, whereas upper BSEC OTPs OTP areas only support one time 32-bit programming, they and are automatically locked by the driver. }} The BSEC OTP areas can be written by 32-bit word starting at OTP {{highlight|N}}, as follows: # {{highlight|'''write''' OTP '''N'''}} word by word {{Board$}} dd if={{highlightParam|/tmp/file}} of=/sys/bus/nvmem/devices/stm32-romem0/nvmem bs=4 seek={{highlight|N}} or # {{highlight|'''write''' OTP '''N'''}}, all the file in one request {{Board$}} dd if={{highlightParam|/tmp/file}} of=/sys/bus/nvmem/devices/stm32-romem0/nvmem seek={{highlight|4*N}} oflag=seek_bytes With a file {{highlightParam|/tmp/file}} containing the OTP data to write, its size is 32-bit word aligned;, for example: # Create a 4 bytes length file filled with ones, e.g. 0xffffffff) {{Board$}} dd if=/dev/zero count=1 bs=4 | tr '\000' '\377' > file # Create a 4 bytes length file, here 0x00000001 to update one OTP {{Board$}} echo -n -e '\x01\x00\x00\x00' > {{highlightParam|/tmp/file}} # Create a 8 bytes length file, here 0x67452301 0xEFCDAB89 to update two OTPs {{Board$}} echo -n -e '\x01\x23\x45\x67\x89\xAB\xCD\xEF' > {{highlightParam|/tmp/file}} A lower OTP area can be written several timetimes for a bit per bit update if it is not locked. An upper OTP dataarea can be written only if it is allowed in [[BSEC_device_tree_configuration#BSEC_node_append|secure world device tree]], and only one time; when once. When the upper OTP is written, it is permanent locked at the end of the NVMEM request to an avoid ECC issue on the second update. For the first example with bs= = 4, this lock is performed after each OTP update and, while for the second example with oflag= = seek_bytes the lock , it is done when all the OTPs OTP data in the input file are updated. {{Info|When a new OTP value has been written using this SYSFS interface, it may be necessary to reboot the board before reading it back. The OTP value can'tcannot be read directly after a write because the OTP value is read in a shadow area that is not directly in the OTP area.}} The full example to writeBelow a compete example of writing the upper OTP 60 is: {{Board$}} echo -n -e {{highlight|'\x01\x23\x45\x67'}} > /tmp/file hexdump -C /tmp/file 00000000 {{highlight|01 23 45 67}} |.#Eg| 00000004 {{Board$}} dd if=/tmp/file of=/sys/bus/nvmem/devices/stm32-romem0/nvmem bs=4 seek={{highlightParam|60}} {{Board$}} reboot<< >> {{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem .... {{highlightParam|000000f0}} {{highlight|01 23 45 67}} 00 00 00 00 00 00 00 00 00 00 00 00 |.#Eg............| .... The associated output in [[STM32CubeProgrammer#How_to_fuse_STM32MP15x_OTP|STM32CubeProgrammer]] is: <br> OTP REGISTERS: --------------------------------------------------------------------------- ID | value | status --------------------------------------------------------------------------- ... 060 | 0x67452301 | 0x40000000 |_[30] Permanent write lock or in [[How_to_update_OTP_with_U-Boot|U-Boot]] {{U-Boot$}} > fuse read 0 0 96 ... Word 0x0000003c: 67452301 00000000 00000000 00000000 ... ==How to trace and debug the framework=====How to trace===[[Ftrace]] can be used to trace the NVMEM framework: {{Board$}} cd /sys/kernel/debug/tracing {{Board$}} cat available_filter_functions | grep nvmem # Show available filter functions rtc_nvmem_register rtc_nvmem_unregister nvmem_reg_read bin_attr_nvmem_read ... Enable the kernel function tracer, then start using nvmem and display the result: {{Board$}} echo function > current_tracer {{Board$}} echo "*nvmem*" > set_ftrace_filter # Trace all nvmem filter functions {{Board$}} echo 1 > tracing_on # start ftrace {{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem # dump nvmem 00000000 17 00 00 00 01 80 00 00 00 00 00 00 00 00 00 00 |................| ... {{Board$}} echo 0 > tracing_on # stop ftrace {{Board$}} cat trace # tracer: function # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | hexdump-478 [000] .... 423.502278: bin_attr_nvmem_read <-sysfs_kf_bin_read hexdump-478 [000] .... 423.502290: nvmem_reg_read <-bin_attr_nvmem_read hexdump-478 [000] .... 423.515804: bin_attr_nvmem_read <-sysfs_kf_bin_read ==References== <references /> <noinclude> {{ArticleBasedOnModel | Framework_overview_article_model}} {{PublicationRequestId | 10397 | 2019-01-21 | AnneJ26423 | 2023-03-10 | (previous :10397 AnneJ)}} [[Category:Persistent storage]]</noinclude>
(26 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
|MPUs checklist=STM32MP13x,STM32MP15x |
|MPUs checklist=STM32MP13x,STM32MP15x |
||
}}</noinclude> |
}}</noinclude> |
||
− | + | ||
− | This article introduces how NVMEM Linux<sup>®</sup> framework manages BSEC OTP data and how to read/write from/to it.<p> |
+ | This article introduces how the NVMEM Linux<sup>®</sup> framework manages BSEC OTP data and how to read/write from/to it.<p> |
==Framework purpose== |
==Framework purpose== |
||
− | The NVMEM Linux<sup>®</sup> framework provides a generic interface for |
+ | The NVMEM Linux<sup>®</sup> framework provides a generic interface for '''non-volatile memory data''' devices such as: |
* OTP (one-time programmable) fuses |
* OTP (one-time programmable) fuses |
||
* EEPROM |
* EEPROM |
||
− | It offers kernel space and user space interfaces to read |
+ | It offers kernel space and user space interfaces to read/write data such as analog calibration data or MAC address. |
==System overview== |
==System overview== |
||
− | {{ ImageMap|Image:NVMEM_overview.png |
+ | {{ ImageMap|Image:NVMEM_overview.png {{!}} 800px {{!}} center{{!}} |
rect 470 142 599 173 [[NVMEM_overview#API description|NVMEM sysfs interface]] |
rect 470 142 599 173 [[NVMEM_overview#API description|NVMEM sysfs interface]] |
||
rect 601 233 749 267 [[NVMEM_overview#API description|NVMEM consumers interface]] |
rect 601 233 749 267 [[NVMEM_overview#API description|NVMEM consumers interface]] |
||
rect 480 660 600 700 [[BSEC internal peripheral]] |
rect 480 660 600 700 [[BSEC internal peripheral]] |
||
− | rect 480 536 601 577 [[OP-TEE OTP |
+ | rect 480 536 601 577 [[OP-TEE OTP overview|BSEC PTA ]] |
rect 232 532 320 570 [[OP-TEE_overview|OP-TEE]] |
rect 232 532 320 570 [[OP-TEE_overview|OP-TEE]] |
||
rect 479 453 600 492 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]] |
rect 479 453 600 492 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]] |
||
Line 25: | Line 25: | ||
===Component description=== |
===Component description=== |
||
* '''NVMEM user''' (user space) |
* '''NVMEM user''' (user space) |
||
− | The user can use the NVMEM sysfs interface |
+ | The user can use the NVMEM sysfs interface from a user terminal or a custom application to read/write data from/to NVMEM devices, and from user space. |
* '''NVMEM user''' (kernel space) |
* '''NVMEM user''' (kernel space) |
||
− | + |
The 'foo_driver' could be any driver in kernel space that uses the NVMEM API to read/write data from/to NVMEM devices (such as the analog calibration data used by an ADC driver). |
|
* '''NVMEM framework''' (kernel space) |
* '''NVMEM framework''' (kernel space) |
||
The NVMEM core provides sysfs interface and NVMEM API. They can be used to implement NVMEM user and NVMEM controller drivers. |
The NVMEM core provides sysfs interface and NVMEM API. They can be used to implement NVMEM user and NVMEM controller drivers. |
||
Line 35: | Line 35: | ||
The TEE framework provides [[OP-TEE_overview#TEE_Client_API|TEE client API]] to communicate with secure services, as the services provided by the OP-TEE Linux<sup>®</sup> driver. |
The TEE framework provides [[OP-TEE_overview#TEE_Client_API|TEE client API]] to communicate with secure services, as the services provided by the OP-TEE Linux<sup>®</sup> driver. |
||
* ''' OP-TEE''' (Secure) |
* ''' OP-TEE''' (Secure) |
||
− | The [[OP-TEE overview|'''OP-TEE secure OS''']] is running on the Cortex-A in [[Security_overview|secure mode]] and exposes secure service with '''Trusted Applications (TA)''', as [[OP-TEE OTP |
+ | The [[OP-TEE overview|'''OP-TEE secure OS''']] is running on the Cortex-A in [[Security_overview|secure mode]] and exposes secure service with '''Trusted Applications (TA)''', as [[OP-TEE OTP overview|BSEC PTA ]]. |
* '''NVMEM hardware''' |
* '''NVMEM hardware''' |
||
− | NVMEM |
+ | NVMEM controllers such as the ''BSEC internal peripheral''<ref name="BSEC internal peripheral">[[BSEC internal peripheral]]</ref> |
===API description=== |
===API description=== |
||
The NVMEM kernel documentation<ref name="documentation_nvmem">{{CodeSource | Linux kernel | Documentation/driver-api/nvmem.rst}}, NVMEM subsytem kernel documentation</ref> describes: |
The NVMEM kernel documentation<ref name="documentation_nvmem">{{CodeSource | Linux kernel | Documentation/driver-api/nvmem.rst}}, NVMEM subsytem kernel documentation</ref> describes: |
||
* Kernel space API for NVMEM '''providers''' and NVMEM '''consumers'''. |
* Kernel space API for NVMEM '''providers''' and NVMEM '''consumers'''. |
||
− | * |
+ | * User space binary interface (sysfs). |
See also ''sysfs-bus-nvmem''<ref name="nvmem_abi">{{CodeSource | Linux kernel | Documentation/ABI/stable/sysfs-bus-nvmem}}, NVMEM ABI documentation</ref> ABI documentation. |
See also ''sysfs-bus-nvmem''<ref name="nvmem_abi">{{CodeSource | Linux kernel | Documentation/ABI/stable/sysfs-bus-nvmem}}, NVMEM ABI documentation</ref> ABI documentation. |
||
==Configuration== |
==Configuration== |
||
===Kernel configuration=== |
===Kernel configuration=== |
||
− | Activate NVMEM framework in the kernel configuration through the Linux<sup>®</sup> menuconfig tool |
+ | Activate NVMEM framework in the kernel configuration through the Linux<sup>®</sup> menuconfig tool (see [[Menuconfig or how to configure kernel | Menuconfig or how to configure kernel]]) with CONFIG_NVMEM = y: |
Device Drivers ---> |
Device Drivers ---> |
||
[*] NVMEM Support ---> |
[*] NVMEM Support ---> |
||
Line 57: | Line 57: | ||
* The NVMEM data providers<ref name="nvmem dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem.yaml}}, NVMEM device tree bindings</ref> |
* The NVMEM data providers<ref name="nvmem dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem.yaml}}, NVMEM device tree bindings</ref> |
||
* The NVMEM data consumers<ref name="nvmem-consumer dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem-consumer.yaml}}, NVMEM consumer device tree bindings</ref> |
* The NVMEM data consumers<ref name="nvmem-consumer dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem-consumer.yaml}}, NVMEM consumer device tree bindings</ref> |
||
− | The ''BSEC internal peripheral''<ref name="BSEC internal peripheral"/> device tree bindings are |
+ | The ''BSEC internal peripheral''<ref name="BSEC internal peripheral"/> device tree bindings are described in the [[BSEC device tree configuration]] article. |
==How to use the framework== |
==How to use the framework== |
||
===How to use NVMEM with sysfs interface=== |
===How to use NVMEM with sysfs interface=== |
||
====How to list NVMEM devices==== |
====How to list NVMEM devices==== |
||
− | The available NVMEM devices can be listed in sysfs directory {{Highlight|/sys/bus/nvmem/devices}} |
+ | The available NVMEM devices can be listed in sysfs directory {{Highlight|/sys/bus/nvmem/devices}}.
|
− | Example |
+ | Example of '''listing''' nvmem devices: |
+ | BSEC is '''stm32-romem0''' |
||
{{Board$}} ls /sys/bus/nvmem/devices/ |
{{Board$}} ls /sys/bus/nvmem/devices/ |
||
stm32-romem0 |
stm32-romem0 |
||
− | ====How to read |
+ | ====How to read OTP areas using NVMEM==== |
− | + |
The user space can read/write the raw NVMEM file located at {{Highlight|/sys/bus/nvmem/devices/*/nvmem}}.
|
|
− | For BSEC, the NVEM '''stm32-romem0''' device |
+ | For BSEC, the NVEM is the '''stm32-romem0''' device. The content of '''non-secure OTP areas''' can be read but the '''secured OTP areas''' are masked, and their values replaced by 0. |
− | Normally only the 32 lower |
+ | Normally only the 32 lower OTP data can be accessed, the upper OTP data being restricted to security. If the user needs more than the 32 lower OTP data, this can be managed by an exception described in [[BSEC device tree configuration]]. |
− | * Example |
+ | * Example of '''reading''' all nvmem data on stm32-romem0 devices |
{{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem of=/tmp/file |
{{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem of=/tmp/file |
||
− | * Example |
+ | * Example of '''displaying''' all nvmem data |
{{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem |
{{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem |
||
− | {{Info|A dedicated page |
+ | {{Info|A dedicated page describes the OTP area mapping for [[STM32MP15_OTP_mapping|STM32MP13]] and [[STM32MP15_OTP_mapping|STM32MP15]].}} |
− | ====How to write BSEC |
+ | ====How to write BSEC OTP data using NVMEM==== |
{{Warning|The below examples show how to write data to an NVMEM device. This may cause unrecoverable damage to the STM32 device (for example when writing to an OTP area)}} |
{{Warning|The below examples show how to write data to an NVMEM device. This may cause unrecoverable damage to the STM32 device (for example when writing to an OTP area)}} |
||
− | {{Info| Note that lower BSEC |
+ | {{Info| Note that lower BSEC OTP areas are using 2:1 redundancy, so they can be written bit per bit, whereas upper BSEC OTP areas only support one time 32-bit programming and are automatically locked by the driver.}} |
− | The BSEC OTP can be written by 32-bit word starting at OTP {{highlight|N}} as follows: |
+ | The BSEC OTP areas can be written by 32-bit word starting at OTP {{highlight|N}}, as follows: |
# {{highlight|'''write''' OTP '''N'''}} word by word |
# {{highlight|'''write''' OTP '''N'''}} word by word |
||
Line 98: | Line 99: | ||
{{Board$}} dd if={{highlightParam|/tmp/file}} of=/sys/bus/nvmem/devices/stm32-romem0/nvmem seek={{highlight|4*N}} oflag=seek_bytes |
{{Board$}} dd if={{highlightParam|/tmp/file}} of=/sys/bus/nvmem/devices/stm32-romem0/nvmem seek={{highlight|4*N}} oflag=seek_bytes |
||
− | With a file {{highlightParam|/tmp/file}} containing the OTP data to write, its size is 32-bit word aligned |
+ | With a file {{highlightParam|/tmp/file}} containing the OTP data to write, its size is 32-bit word aligned, for example: |
# Create a 4 bytes length file filled with ones, e.g. 0xffffffff) |
# Create a 4 bytes length file filled with ones, e.g. 0xffffffff) |
||
Line 107: | Line 108: | ||
{{Board$}} echo -n -e '\x01\x23\x45\x67\x89\xAB\xCD\xEF' > {{highlightParam|/tmp/file}} |
{{Board$}} echo -n -e '\x01\x23\x45\x67\x89\xAB\xCD\xEF' > {{highlightParam|/tmp/file}} |
||
− | A lower OTP can be written several |
+ | A lower OTP area can be written several times for a bit per bit update if it is not locked. |
− | An upper OTP |
+ | An upper OTP area can be written only if it is allowed in [[BSEC_device_tree_configuration#BSEC_node_append|secure world device tree]], and only once. When the upper OTP is written, it is permanent locked at the end of the NVMEM request to an avoid ECC issue on the second update. For the first example with bs = 4, this lock is performed after each OTP update, while for the second example with oflag = seek_bytes, it is done when all the OTP data in the input file are updated. |
− | {{Info|When a new OTP value has been written using this SYSFS interface, it may be necessary to reboot the board before reading it back. The OTP value |
+ | {{Info|When a new OTP value has been written using this SYSFS interface, it may be necessary to reboot the board before reading it back. The OTP value cannot be read directly after a write because the OTP value is read in a shadow area that is not directly in the OTP area.}} |
− | + |
Below a compete example of writing the upper OTP 60: |
|
{{Board$}} echo -n -e {{highlight|'\x01\x23\x45\x67'}} > /tmp/file |
{{Board$}} echo -n -e {{highlight|'\x01\x23\x45\x67'}} > /tmp/file |
||
Line 144: | Line 145: | ||
... |
... |
||
− | ==How to trace |
+ | ==How to trace the framework== |
− | |||
[[Ftrace]] can be used to trace the NVMEM framework: |
[[Ftrace]] can be used to trace the NVMEM framework: |
||
{{Board$}} cd /sys/kernel/debug/tracing |
{{Board$}} cd /sys/kernel/debug/tracing |
||
Line 182: | Line 182: | ||
<noinclude> |
<noinclude> |
||
{{ArticleBasedOnModel | Framework_overview_article_model}} |
{{ArticleBasedOnModel | Framework_overview_article_model}} |
||
− | {{PublicationRequestId | |
+ | {{PublicationRequestId | 26423 | 2023-03-10 | (previous :10397 AnneJ)}} |
[[Category:Persistent storage]] |
[[Category:Persistent storage]] |
||
</noinclude> |
</noinclude> |