Difference between revisions of "NVMEM overview"

[quality revision] [unchecked revision]
m
 
(add information on how to read NVMEM information in basic and trusted boot chains (BZ68116))





SUMMARY

This article introduces how NVMEM Linux® framework manages BSEC OTP data and how to read/write from/to it.

1 Framework purpose[edit]

The NVMEM Linux® framework provides a generic interface for the device non-volatile memory data 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]

NVMEM sysfs interface NVMEM consumers interface BSEC internal peripheral
NVMEM system overview
Template:WarningImageMapOverlay

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) from user space.

  • NVMEM user (kernel space)

User drivers can use the NVMEM API to read/write data from/to NVMEM device(s) from kernel space (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 BSEC Linux® driver that exposes OTP data to the core.

  • NVMEM hardware

NVMEM controller(s) 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 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, Menuconfig or how to configure kernel (CONFIG_NVMEM=y):

Device Drivers  --->
   [*] NVMEM Support  --->

3.2 Device tree configuration[edit]

The NVMEM data device tree bindings[4] describe:

  • The location of non-volatile memory data
  • The NVMEM data providers
  • The NVMEM data consumers

4 How to use the framework[edit]

4.1 How to use NVMEM with sysfs interface[edit]

The available NVMEM devices can be listed in sysfs:

Board $> ls /sys/bus/nvmem/devices/                                            # Example to list nvmem devices
stm32-romem0

The data content of an NVMEM device can be dumped to a binary file: , and then displayed.

For the Basic boot chain (using U-Boot SPL), it is impossible to read any upper NVMEM information because SMC feature is not available (CONFIG_HAVE_ARM_SMCCC).

Board $> catdd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem > vnmem of=/tmp/file bs=4 count=32                  # Example to read nvmem data content

The data content of an NVMEM device can be displayed:

Board $> hexdump -C -v /tmp/file                  # Example to display nvmem data content

For the Trusted boot chain (using TF-A), SMC feature is available. It is then possible to access to some upper NVMEM information, only if access is authorized by the device tree configuration. This is the case of the MAC address, presented below.

Board $> dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem
vnmem of=/tmp/file skip=57 bs=4 count=2 status=none                  # Example to read MAC address
Board $> hexdump -C -v /tmp/file                  # Example to display MAC address

Note that a specific chapter of the reference manual is dedicated to OTP mapping, in which information is detailed.

Warning.png 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 full data content of an NVMEM device can be written as follows:

Board $> cat file > /sys/bus/nvmem/devices/stm32-romem0/nvmem                  # Example to write nvmem data content

Example of 32-bit data word writing (filling it with ones) in OTP n°95:

Board $> dd if=/dev/zero count=1 bs=4 | tr '\000' '\377' > file                # Create a 4 bytes length file filled with ones, e.g. 0xffffffff)
Board $> dd if=file bs=4 seek=95 of=/sys/bus/nvmem/devices/stm32-romem0/nvmem  # Write it (32-bits, e.g. 4bytes) to OTP data 95

5 How to trace and debug the framework[edit]

5.1 How to trace[edit]

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

6 References[edit]

<noinclude>

{{ArticleBasedOnModel | [[Framework overview article model]]}}
{{ArticleMainWriter | FabriceG}}
{{ReviewersList | FabriceG, LionelD}}
{{ArticleApprovedVersion | FabriceG | LionelD | No previous approved version | AnneJ - 21Jan'19 - 10397 | 21Jan'19}}
[[Category:Persistent storage]]</noinclude>


'''SUMMARY '''<br>

This article introduces how NVMEM Linux<sup>&reg;</sup> framework manages BSEC OTP data and how to read/write from/to it.<p>


==Framework purpose==
The NVMEM Linux<sup>&reg;</sup> framework provides a generic interface for the device '''non-volatile memory data''' 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{{!}} NVMEM system overview <br/> {{WarningImageMapOverlay}}
rect 400 232 500 272 [[NVMEM_overview#API description|NVMEM sysfs interface]]
rect 612 335 752 368 [[NVMEM_overview#API description|NVMEM consumers interface]]
rect 478 563 599 605 [[BSEC internal peripheral]]
}}
===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) from user space.
* '''NVMEM user''' (kernel space)
User drivers can use the NVMEM API to read/write data from/to NVMEM device(s) from kernel space (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 BSEC Linux<sup>&reg;</sup> driver that exposes OTP data to the core.
* '''NVMEM hardware'''
NVMEM controller(s) 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/nvmem/nvmem.txt}}, NVMEM subsytem kernel documentation</ref> describes:
* Kernel space API for NVMEM '''providers''' and NVMEM '''consumers'''.
* Userspace 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>&reg;</sup> menuconfig tool, [[Menuconfig or how to configure kernel | Menuconfig or how to configure kernel ]] (CONFIG_NVMEM=y):
 Device Drivers  --->
    [*] NVMEM Support  --->
===Device tree configuration===
The NVMEM data device tree bindings<ref name="nvmem dt bindings">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/nvmem/nvmem.txt}}, NVMEM data device tree bindings</ref> describe:
* The location of non-volatile memory data
* The NVMEM data providers
* The NVMEM data consumers

==How to use the framework==
===How to use NVMEM with sysfs interface===
The available NVMEM devices can be listed in sysfs:
 {{Board$}} ls /sys/bus/nvmem/devices/                                            # {{highlight|Example to '''list''' nvmem devices}}
 stm32-romem0
The data content of an NVMEM device can be dumped to a binary file:
 {{Board$}} cat , and then displayed.

For the Basic boot chain (using [[U-Boot_overview#SPL:_FSBL_for_basic_boot|U-Boot SPL]]), it is impossible to read any upper NVMEM information because SMC feature is not available (CONFIG_HAVE_ARM_SMCCC).
 {{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem > file                  vnmem of=/tmp/file bs=4 count=32                  # {{highlight|Example to '''read''' nvmem data content}}The data content of an NVMEM device can be displayed:
 {{Board$}} hexdump -C -v  {{Board$}} hexdump -C -v /tmp/file                  # {{highlight|Example to '''display''' nvmem data content}}

For the Trusted boot chain (using [[TF-A overview|TF-A]]), SMC feature is available. It is then possible to access to some upper NVMEM information, only if access is authorized by the device tree configuration. This is the case of the MAC address, presented below.
 {{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem
{{vnmem of=/tmp/file skip=57 bs=4 count=2 status=none                  # {{highlight|Example to '''read''' MAC address}}
 {{Board$}} hexdump -C -v /tmp/file                  # {{highlight|Example to '''display''' MAC address}}

Note that a specific chapter of the [[STM32MP15 resources|reference manual]] is dedicated to OTP mapping, in which information is detailed.

{{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)}}
The full data content of an NVMEM device can be written as follows:
 {{Board$}} cat file > /sys/bus/nvmem/devices/stm32-romem0/nvmem                  # {{highlight|Example to '''write''' nvmem data content}}
Example of 32-bit data word writing (filling it with ones) in OTP n°95:
 {{Board$}} dd if=/dev/zero count=1 bs=4 | tr '\000' '\377' > file                # Create a 4 bytes length file filled with ones, e.g. 0xffffffff)
 {{Board$}} dd if=file bs=4 seek=95 of=/sys/bus/nvmem/devices/stm32-romem0/nvmem  # Write it (32-bits, e.g. 4bytes) to OTP data 95

==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 />
Line 57: Line 57:
 
  {{Board$}} ls /sys/bus/nvmem/devices/                                            # {{highlight|Example to '''list''' nvmem devices}}
 
  {{Board$}} ls /sys/bus/nvmem/devices/                                            # {{highlight|Example to '''list''' nvmem devices}}
 
  stm32-romem0
 
  stm32-romem0
The data content of an NVMEM device can be dumped to a binary file:
+
The data content of an NVMEM device can be dumped to a binary file, and then displayed.
  {{Board$}} cat /sys/bus/nvmem/devices/stm32-romem0/nvmem > file                  # {{highlight|Example to '''read''' nvmem data content}}
+
 
The data content of an NVMEM device can be displayed:
+
For the Basic boot chain (using [[U-Boot_overview#SPL:_FSBL_for_basic_boot|U-Boot SPL]]), it is impossible to read any upper NVMEM information because SMC feature is not available (CONFIG_HAVE_ARM_SMCCC).
  {{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem
+
  {{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/vnmem of=/tmp/file bs=4 count=32                 # {{highlight|Example to '''read''' nvmem data content}}
  +
{{Board$}} hexdump -C -v /tmp/file                  # {{highlight|Example to '''display''' nvmem data content}}
  +
 
  +
For the Trusted boot chain (using [[TF-A overview|TF-A]]), SMC feature is available. It is then possible to access to some upper NVMEM information, only if access is authorized by the device tree configuration. This is the case of the MAC address, presented below.
  +
  {{Board$}} dd if=/sys/bus/nvmem/devices/stm32-romem0/vnmem of=/tmp/file skip=57 bs=4 count=2 status=none                  # {{highlight|Example to '''read''' MAC address}}
  +
{{Board$}} hexdump -C -v /tmp/file                  # {{highlight|Example to '''display''' MAC address}}
  +
 
  +
Note that a specific chapter of the [[STM32MP15 resources|reference manual]] is dedicated to OTP mapping, in which information is detailed.
  +
 
 
{{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)}}
 
The full data content of an NVMEM device can be written as follows:
 
The full data content of an NVMEM device can be written as follows:

Attachments

Discussions