Difference between revisions of "NVMEM overview"

[quality revision] [quality revision]
m
m
Applicable for STM32MP13x lines, STM32MP15x lines

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 BSEC PTA OP-TEE OP-TEE linux driver TEE Client APINVMEM overview.png

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.

  • 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) 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  --->
      <*>   STMicroelectronics STM32 factory-programmed memory support

3.2 Device tree configuration[edit]

The NVMEM data device tree bindings describe:

  • The location of non-volatile memory data
  • The NVMEM data providers[4]
  • The NVMEM data consumers[5]

The BSEC internal peripheral[1] device tree bindings are explained in 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 nvmem devices: BSEC is stm32-romem0

 ls /sys/bus/nvmem/devices/
stm32-romem0

4.1.2 How to read OTPs using NVMEM[edit]

Userspace can read/write the raw NVMEM file located at: /sys/bus/nvmem/devices/*/nvmem

For BSEC, the NVEM stm32-romem0 device, the content of non-secure OTPs can be read but the secured OTPs are masked, theirs values are replaced by 0.

Normally only the 32 lower OTPs can be accessed and the upper OTPS is restricted to security. If user needs more than the 32 lower OTPs, there is an exception management explained in BSEC device tree configuration.

  • Example to read all nvmem data content on stm32-romem0 devices
 dd if=/sys/bus/nvmem/devices/stm32-romem0/nvmem of=/tmp/file
  • Example to display nvmem data content
 hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem
Info white.png Information
A dedicated page describe the OTP mapping for STM32MP13 and STM32MP15.

4.1.3 How to write BSEC OTPs using NVMEM[edit]

Warning white.png Warning
In OpenSTLinux it is not possible to write data to the NVMEM BSEC device with Linux driver; BSEC is defined as a read only NVMEM device.

OTP can be updated by using STM32CubeProgrammer.

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]



<noinclude>{{ApplicableFor
|MPUs list=STM32MP13x, STM32MP15x
|MPUs checklist=STM32MP13x,STM32MP15x
}}</noinclude>

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{{!}}
rect 470 160 600 200 [[NVMEM_overview#API description|NVMEM sysfs interface]]
rect 600 260 750 300 [[NVMEM_overview#API description|NVMEM consumers interface]]
rect 480 660 600 700 [[BSEC internal peripheral]]
rect 480 570 600 615 [[OP-TEE OTP interfacePTA overview|BSEC PTA]]
rect 230 560 315 600 [[OP-TEE_overview|OP-TEE]]
rect 480 480 600 520 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]]
rect 525 445 615 475 [[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) 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.
* '''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>&reg;</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 interfacePTA overview|BSEC PTA]].
* '''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/driver-api/nvmem.rst}}, 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  ---><*>   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 explained in [[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: BSEC is '''stm32-romem0'''
 {{Board$}} ls /sys/bus/nvmem/devices/
 stm32-romem0

====How to read OTPs using NVMEM====

Userspace can read/write the raw NVMEM file located at: {{Highlight|/sys/bus/nvmem/devices/*/nvmem}}

For BSEC, the NVEM '''stm32-romem0''' device, the content of '''non-secure OTPs''' can be read but the '''secured OTPs''' are masked, theirs values are replaced by 0.

Normally only the 32 lower OTPs can be accessed and the upper OTPS is restricted to security. If user needs more than the 32 lower OTPs, there is an exception management explained in [[BSEC device tree configuration]].

* Example to '''read''' 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 content
 {{Board$}} hexdump -C -v /sys/bus/nvmem/devices/stm32-romem0/nvmem

{{Info|A dedicated page describe the OTP mapping for [[STM32MP15_OTP_mapping|STM32MP13]] and [[STM32MP15_OTP_mapping|STM32MP15]].}}

====How to write BSEC OTPs using NVMEM====

{{Warning|In OpenSTLinux it is not possible to write data to the NVMEM BSEC device with Linux driver; BSEC is defined as a read only NVMEM device.}}

OTP can be updated by using STM32CubeProgrammer.

==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 | AnneJ}}
[[Category:Persistent storage]]</noinclude>
Line 16: Line 16:
 
rect 600 260 750 300 [[NVMEM_overview#API description|NVMEM consumers interface]]
 
rect 600 260 750 300 [[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 570 600 615 [[OP-TEE OTP interface|BSEC PTA]]
+
rect 480 570 600 615 [[OP-TEE OTP PTA overview|BSEC PTA]]
 
rect 230 560 315 600 [[OP-TEE_overview|OP-TEE]]
 
rect 230 560 315 600 [[OP-TEE_overview|OP-TEE]]
 
rect 480 480 600 520 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]]
 
rect 480 480 600 520 [[OP-TEE_overview#TEE_Linux_driver|OP-TEE linux driver]]
Line 33: Line 33:
 
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>&reg;</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>&reg;</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 interface|BSEC PTA]].
+
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 hardware'''
 
NVMEM controller(s) such as the ''BSEC internal peripheral''<ref name="BSEC internal peripheral">[[BSEC internal peripheral]]</ref>
 
NVMEM controller(s) such as the ''BSEC internal peripheral''<ref name="BSEC internal peripheral">[[BSEC internal peripheral]]</ref>