Pull request for efi-2021-10-rc2-2

Documentation:
 
 * Require Sphinx >= 2.4.4 for 'make htmldocs'
 * Move devicetree documentation to restructured text and update it
 * Document stm32mp1 devicetree bindings
 
 UEFI
 
 * Extend measurement to UEFI variables and ExitBootServices()
 * Support Uri() node in devicetree to text protocol
 * Add Linux magic token to RISC-V EFI test binaries
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmEYlbcACgkQxIHbvCwF
 GsRP6g/8C1HWK4ZKJspHBt3ib09XwiJHTTVym//Crqo1+J32scS32Uktx6PvOODD
 axmE60cSblDKL3+1uVRMRF2rEGta3pjYyPe/ie7VhqvFU5c7BxHbBSAe0fKTXWtR
 7DVFKn4f0Yv1k3MD/WV/3L9LXEJeOC+UHANNUYfQsuC42kPhq3wZTrHJdJeqr2R3
 VBaxk/xpMXsHkMZF+xmhPd6BtaYC6CMw57HHRYlKCOZbIYaV/ncdR1/am2/Yx+cF
 w9hPVStZynp0E6oykbNiClIrpg7XknkS6Pf70UC9ZbX2mc3vOoXf/ZfC0Wgx/aBf
 ifIszIKXlhHY/1bzwR6hLP8TjOGKZzF/rjgF95N8KJWVccyYWYbyO30WTvFmD4/D
 LXd0hH2olXGE8ZumvWtyHuHTel6kO4FVn1Wk+symofH8Wsj29o0ZjvhJoCgQRu4+
 Ngm3JMVcO7DCkPc+tCCahZL1N06qdsUg2d7j/uM/M92A/X3lkUMRP2HsySHuE7Gg
 3Oc3hcazauxiz0gygAWFGbGqs9wrPnkPcRsrn8cQkjyK9a4JVsJfjUwKO3ZvTjVr
 ID24pQhEeim0elDOaOCxceCoes3zIgVAW058r3/jN+MaCSzIIWEG9plPIdvAejGi
 SjNYK+aWnoWrAVG6rsXO+EhWj49qekvB4XKSb3JV1Z9KP9WAN7E=
 =GyC+
 -----END PGP SIGNATURE-----

Merge tag 'efi-2021-10-rc2-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2021-10-rc2-2

Documentation:

* Require Sphinx >= 2.4.4 for 'make htmldocs'
* Move devicetree documentation to restructured text and update it
* Document stm32mp1 devicetree bindings

UEFI

* Extend measurement to UEFI variables and ExitBootServices()
* Support Uri() node in devicetree to text protocol
* Add Linux magic token to RISC-V EFI test binaries
This commit is contained in:
Tom Rini 2021-08-15 13:42:42 -04:00
commit fdc4fda330
29 changed files with 845 additions and 1244 deletions

View file

@ -33,7 +33,10 @@
.globl ImageBase
ImageBase:
.short IMAGE_DOS_SIGNATURE /* 'MZ' */
.skip 58 /* 'MZ' + pad + offset == 64 */
.skip 46 /* 'MZ' + pad + offset == 64 */
.long 0x43534952 /* Linux magic "RISCV */
.long 0x00000056
.long 0x05435352 /* Linux magic2 "RSC\x05*/
.long pe_header - ImageBase /* Offset to the PE header */
pe_header:
.long IMAGE_NT_SIGNATURE /* 'PE' */
@ -72,7 +75,7 @@ extra_header_fields:
.long 0x8 /* FileAlignment */
.short 0 /* MajorOperatingSystemVersion */
.short 0 /* MinorOperatingSystemVersion */
.short 0 /* MajorImageVersion */
.short 1 /* MajorImageVersion */
.short 0 /* MinorImageVersion */
.short 0 /* MajorSubsystemVersion */
.short 0 /* MinorSubsystemVersion */

View file

@ -1,230 +0,0 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2011 The Chromium OS Authors.
Device Tree Control in U-Boot
=============================
This feature provides for run-time configuration of U-Boot via a flat
device tree (fdt). U-Boot configuration has traditionally been done
using CONFIG options in the board config file. This feature aims to
make it possible for a single U-Boot binary to support multiple boards,
with the exact configuration of each board controlled by a flat device
tree (fdt). This is the approach recently taken by the ARM Linux kernel
and has been used by PowerPC for some time.
The fdt is a convenient vehicle for implementing run-time configuration
for three reasons. Firstly it is easy to use, being a simple text file.
It is extensible since it consists of nodes and properties in a nice
hierarchical format.
Finally, there is already excellent infrastructure for the fdt: a
compiler checks the text file and converts it to a compact binary
format, and a library is already available in U-Boot (libfdt) for
handling this format.
The dts directory contains a Makefile for building the device tree blob
and embedding it in your U-Boot image. This is useful since it allows
U-Boot to configure itself according to what it finds there. If you have
a number of similar boards with different peripherals, you can describe
the features of each board in the device tree file, and have a single
generic source base.
To enable this feature, add CONFIG_OF_CONTROL to your board config file.
What is a Flat Device Tree?
---------------------------
An fdt can be specified in source format as a text file. To read about
the fdt syntax, take a look at the specification here:
https://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf
You also might find this section of the Linux kernel documentation
useful: (access this in the Linux kernel source code)
Documentation/devicetree/booting-without-of.txt
There is also a mailing list:
http://lists.ozlabs.org/listinfo/devicetree-discuss
In case you are wondering, OF stands for Open Firmware.
Tools
-----
To use this feature you will need to get the device tree compiler. This is
provided by U-Boot automatically. If you have a system version of dtc
(typically in the 'device-tree-compiler' package), it is currently not used.
If you want to build your own dtc, it is kept here:
git://git.kernel.org/pub/scm/utils/dtc/dtc.git
For example:
$ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
$ cd dtc
$ make
$ sudo make install
Then run the compiler (your version will vary):
$ dtc -v
Version: DTC 1.2.0-g2cb4b51f
$ make tests
$ cd tests
$ ./run_tests.sh
********** TEST SUMMARY
* Total testcases: 1371
* PASS: 1371
* FAIL: 0
* Bad configuration: 0
* Strange test result: 0
You will also find a useful fdtdump utility for decoding a binary file, as
well as fdtget/fdtput for reading and writing properties in a binary file.
Where do I get an fdt file for my board?
----------------------------------------
You may find that the Linux kernel has a suitable file. Look in the
kernel source in arch/<arch>/boot/dts.
If not you might find other boards with suitable files that you can
modify to your needs. Look in the board directories for files with a
.dts extension.
Failing that, you could write one from scratch yourself!
Configuration
-------------
Use:
#define CONFIG_DEFAULT_DEVICE_TREE "<name>"
to set the filename of the device tree source. Then put your device tree
file into
board/<vendor>/dts/<name>.dts
This should include your CPU or SOC's device tree file, placed in
arch/<arch>/dts, and then make any adjustments required.
If CONFIG_OF_EMBED is defined, then it will be picked up and built into
the U-Boot image (including u-boot.bin). This is suitable for debugging
and development only and is not recommended for production devices.
If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
a u-boot.dtb file alongside u-boot-nodtb.bin. A common approach is then to
join the two:
cat u-boot-nodtb.bin u-boot.dtb >image.bin
and then flash image.bin onto your board. Note that U-Boot creates
u-boot-dtb.bin which does the above step for you also. Resulting
u-boot.bin is a copy of u-boot-dtb.bin in this case. If you are using
CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
tree binary.
If CONFIG_OF_BOARD is defined, a board-specific routine will provide the
device tree at runtime, for example if an earlier bootloader stage creates
it and passes it to U-Boot.
If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on
startup. This is only useful for sandbox. Use the -d flag to U-Boot to
specify the file to read.
You cannot use more than one of these options at the same time.
To use a device tree file that you have compiled yourself, pass
EXT_DTB=<filename> to 'make', as in:
make EXT_DTB=boot/am335x-boneblack-pubkey.dtb
Then U-Boot will copy that file to u-boot.dtb, put it in the .img file
if used, and u-boot-dtb.bin.
If you wish to put the fdt at a different address in memory, you can
define the "fdtcontroladdr" environment variable. This is the hex
address of the fdt binary blob, and will override either of the options.
Be aware that this environment variable is checked prior to relocation,
when only the compiled-in environment is available. Therefore it is not
possible to define this variable in the saved SPI/NAND flash
environment, for example (it will be ignored). After relocation, this
variable will be set to the address of the newly relocated fdt blob.
It is read-only and cannot be changed. It can optionally be used to
control the boot process of Linux with bootm/bootz commands.
To use this, put something like this in your board header file:
#define CONFIG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0"
Build:
After board configuration is done, fdt supported u-boot can be build in two ways:
1) build the default dts which is defined from CONFIG_DEFAULT_DEVICE_TREE
$ make
2) build the user specified dts file
$ make DEVICE_TREE=<dts-file-name>
Relocation, SPL and TPL
-----------------------
U-Boot can be divided into three phases: TPL, SPL and U-Boot proper.
The full device tree is available to U-Boot proper, but normally only a subset
(or none at all) is available to TPL and SPL. See 'Pre-Relocation Support' and
'SPL Support' in doc/driver-model/design.rst for more details.
Using several DTBs in the SPL (CONFIG_SPL_MULTI_DTB)
----------------------------------------------------
In some rare cases it is desirable to let SPL be able to select one DTB among
many. This usually not very useful as the DTB for the SPL is small and usually
fits several platforms. However the DTB sometimes include information that do
work on several platforms (like IO tuning parameters).
In this case it is possible to use CONFIG_SPL_MULTI_DTB. This option appends to
the SPL a FIT image containing several DTBs listed in SPL_OF_LIST.
board_fit_config_name_match() is called to select the right DTB.
If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM
containing the board ID for example), it possible to start with a generic DTB
and then switch over to the right DTB after the detection. For this purpose,
the platform code must call fdtdec_resetup(). Based on the returned flag, the
platform may have to re-initiliaze the DM subusystem using dm_uninit() and
dm_init_and_scan().
Limitations
-----------
U-Boot is designed to build with a single architecture type and CPU
type. So for example it is not possible to build a single ARM binary
which runs on your AT91 and OMAP boards, relying on an fdt to configure
the various features. This is because you must select one of
the CPU families within arch/arm/cpu/arm926ejs (omap or at91) at build
time. Similarly you cannot build for multiple cpu types or
architectures.
That said the complexity reduction by using fdt to support variants of
boards which use the same SOC / CPU can be substantial.
It is important to understand that the fdt only selects options
available in the platform / drivers. It cannot add new drivers (yet). So
you must still have the CONFIG option to enable the driver. For example,
you need to define CONFIG_SYS_NS16550 to bring in the NS16550 driver,
but can use the fdt to specific the UART clock, peripheral address, etc.
In very broad terms, the CONFIG options in general control *what* driver
files are pulled in, and the fdt controls *how* those files work.
--
Simon Glass <sjg@chromium.org>
1-Sep-11

View file

@ -6,4 +6,5 @@ STMicroelectronics
.. toctree::
:maxdepth: 2
st
stm32mp1

68
doc/board/st/st.rst Normal file
View file

@ -0,0 +1,68 @@
.. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
.. sectionauthor:: Patrick Delaunay <patrick.delaunay@st.com>
U-Boot device tree bindings
----------------------------
The U-Boot specific bindings are defined in the U-Boot directory:
doc/device-tree-bindings
* clock
- :download:`clock/st,stm32mp1.txt <../../device-tree-bindings/clock/st,stm32mp1.txt>`
* ram
- :download:`memory-controllers/st,stm32mp1-ddr.txt <../../device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt>`
All the other device tree bindings used in U-Boot are specified in Linux
kernel. Please refer dt bindings from below specified paths in the Linux
kernel binding directory = Documentation/devicetree/bindings/
* acd
- iio/adc/st,stm32-adc.yaml
* clock
- clock/st,stm32-rcc.txt
- clock/st,stm32h7-rcc.txt
- clock/st,stm32mp1-rcc.yaml
* display
- display/st,stm32-dsi.yaml
- display/st,stm32-ltdc.yaml
* gpio
- pinctrl/st,stm32-pinctrl.yaml
* hwlock
- hwlock/st,stm32-hwspinlock.yaml
* i2c
- i2c/st,stm32-i2c.yaml
* mailbox
- mailbox/st,stm32-ipcc.yaml
* mmc
- mmc/arm,pl18x.yaml
* nand
- mtd/st,stm32-fmc2-nand.yaml
- memory-controllers/st,stm32-fmc2-ebi.yaml
* net
- net/stm32-dwmac.yaml
* nvmem
- nvmem/st,stm32-romem.yaml
* remoteproc
- remoteproc/st,stm32-rproc.yaml
* regulator
- regulator/st,stm32mp1-pwr-reg.yaml
- regulator/st,stm32-vrefbuf.yaml
* reset
- reset/st,stm32-rcc.txt
- reset/st,stm32mp1-rcc.txt
* rng
- rng/st,stm32-rng.yaml
* rtc
- rtc/st,stm32-rtc.yaml
* serial
- serial/st,stm32-uart.yaml
* spi
- spi/st,stm32-spi.yaml
- spi/st,stm32-qspi.yaml
* syscon
- arm/stm32/st,stm32-syscon.yaml
* usb
- phy/phy-stm32-usbphyc.yaml
- usb/dwc2.yaml
* watchdog
- watchdog/st,stm32-iwdg.yaml

4
doc/build/gcc.rst vendored
View file

@ -26,8 +26,8 @@ Depending on the build targets further packages maybe needed
sudo apt-get install bc bison build-essential coccinelle \
device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \
liblz4-tool libguestfs-tools libncurses-dev libpython3-dev libsdl2-dev \
libssl-dev lz4 lzma lzma-alone openssl python3 python3-coverage \
python3-pycryptodome python3-pyelftools python3-pytest \
libssl-dev lz4 lzma lzma-alone openssl pkg-config python3 \
python3-coverage python3-pycryptodome python3-pyelftools python3-pytest \
python3-sphinxcontrib.apidoc python3-sphinx-rtd-theme python3-virtualenv \
swig

View file

@ -31,7 +31,7 @@ from load_config import loadConfig
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.3'
needs_sphinx = '2.4.4'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@ -118,19 +118,12 @@ if major >= 3:
else:
extensions.append('cdomain')
if major == 1 and minor < 7:
sys.stderr.write('WARNING: Sphinx 1.7 or greater will be required as of '
'the v2021.04 release\n')
# Ensure that autosectionlabel will produce unique names
autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2
# The name of the math extension changed on Sphinx 1.4
if (major == 1 and minor > 3) or (major > 1):
extensions.append("sphinx.ext.imgmath")
else:
extensions.append("sphinx.ext.pngmath")
extensions.append("sphinx.ext.imgmath")
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@ -345,27 +338,34 @@ htmlhelp_basename = 'TheUBootdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
'papersize': 'a4paper',
# The paper size ('letterpaper' or 'a4paper').
'papersize': 'a4paper',
# The font size ('10pt', '11pt' or '12pt').
'pointsize': '11pt',
# The font size ('10pt', '11pt' or '12pt').
'pointsize': '11pt',
# Latex figure (float) alignment
#'figure_align': 'htbp',
# Latex figure (float) alignment
#'figure_align': 'htbp',
# Don't mangle with UTF-8 chars
'inputenc': '',
'utf8extra': '',
# Don't mangle with UTF-8 chars
'inputenc': '',
'utf8extra': '',
# Additional stuff for the LaTeX preamble.
# Set document margins
'sphinxsetup': '''
hmargin=0.5in, vmargin=1in,
parsedliteralwraps=true,
verbatimhintsturnover=false,
''',
# Additional stuff for the LaTeX preamble.
'preamble': '''
% Use some font with UTF-8 support with XeLaTeX
% Use some font with UTF-8 support with XeLaTeX
\\usepackage{fontspec}
\\setsansfont{DejaVu Sans}
\\setromanfont{DejaVu Serif}
\\setmonofont{DejaVu Sans Mono}
'''
''',
}
# At least one book (translations) may have Asian characters
@ -380,72 +380,6 @@ if cjk_cmd.find("Noto Sans CJK SC") >= 0:
\\setCJKmainfont{Noto Sans CJK SC}
'''
# Fix reference escape troubles with Sphinx 1.4.x
if major == 1 and minor > 3:
latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n'
if major == 1 and minor <= 4:
latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}'
elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)):
latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=1in'
latex_elements['preamble'] += '\\fvset{fontsize=auto}\n'
# Customize notice background colors on Sphinx < 1.6:
if major == 1 and minor < 6:
latex_elements['preamble'] += '''
\\usepackage{ifthen}
% Put notes in color and let them be inside a table
\\definecolor{NoteColor}{RGB}{204,255,255}
\\definecolor{WarningColor}{RGB}{255,204,204}
\\definecolor{AttentionColor}{RGB}{255,255,204}
\\definecolor{ImportantColor}{RGB}{192,255,204}
\\definecolor{OtherColor}{RGB}{204,204,204}
\\newlength{\\mynoticelength}
\\makeatletter\\newenvironment{coloredbox}[1]{%
\\setlength{\\fboxrule}{1pt}
\\setlength{\\fboxsep}{7pt}
\\setlength{\\mynoticelength}{\\linewidth}
\\addtolength{\\mynoticelength}{-2\\fboxsep}
\\addtolength{\\mynoticelength}{-2\\fboxrule}
\\begin{lrbox}{\\@tempboxa}\\begin{minipage}{\\mynoticelength}}{\\end{minipage}\\end{lrbox}%
\\ifthenelse%
{\\equal{\\py@noticetype}{note}}%
{\\colorbox{NoteColor}{\\usebox{\\@tempboxa}}}%
{%
\\ifthenelse%
{\\equal{\\py@noticetype}{warning}}%
{\\colorbox{WarningColor}{\\usebox{\\@tempboxa}}}%
{%
\\ifthenelse%
{\\equal{\\py@noticetype}{attention}}%
{\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}%
{%
\\ifthenelse%
{\\equal{\\py@noticetype}{important}}%
{\\colorbox{ImportantColor}{\\usebox{\\@tempboxa}}}%
{\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}%
}%
}%
}%
}\\makeatother
\\makeatletter
\\renewenvironment{notice}[2]{%
\\def\\py@noticetype{#1}
\\begin{coloredbox}{#1}
\\bf\\it
\\par\\strong{#2}
\\csname py@noticestart@#1\\endcsname
}
{
\\csname py@noticeend@\\py@noticetype\\endcsname
\\end{coloredbox}
}
\\makeatother
'''
# With Sphinx 1.6, it is possible to change the Bg color directly
# by using:
# \definecolor{sphinxnoteBgColor}{RGB}{204,255,255}

View file

@ -0,0 +1,251 @@
.. SPDX-License-Identifier: GPL-2.0+
.. sectionauthor:: Copyright 2011 The Chromium OS Authors
Devicetree Control in U-Boot
============================
This feature provides for run-time configuration of U-Boot via a flattened
devicetree (fdt).
This feature aims to make it possible for a single U-Boot binary to support
multiple boards, with the exact configuration of each board controlled by
a flattened devicetree (fdt). This is the approach taken by Linux kernel for
ARM and RISC-V and has been used by PowerPC for some time.
The fdt is a convenient vehicle for implementing run-time configuration
for three reasons:
- There is already excellent infrastructure for the fdt: a compiler checks
the text file and converts it to a compact binary format, and a library
is already available in U-Boot (libfdt) for handling this format
- It is extensible since it consists of nodes and properties in a nice
hierarchical format
- It is fairly efficient to read incrementally
The arch/<arch>/dts directories contains a Makefile for building the devicetree
blob and embedding it in the U-Boot image. This is useful since it allows
U-Boot to configure itself according to what it finds there. If you have
a number of similar boards with different peripherals, you can describe
the features of each board in the devicetree file, and have a single
generic source base.
To enable this feature, add CONFIG_OF_CONTROL to your board config file.
What is a Flattened Devicetree?
-------------------------------
An fdt can be specified in source format as a text file. To read about
the fdt syntax, take a look at the specification (dtspec_).
There is also a mailing list (dtlist_) for the compiler and associated
tools.
In case you are wondering, OF stands for Open Firmware. This follows the
convention used in Linux.
Tools
-----
To create flattened device trees the device tree compiler is used. This is
provided by U-Boot automatically. If you have a system version of dtc
(typically in the 'device-tree-compiler' package), that system version is
currently not used.
If you want to build your own dtc, it is kept here::
git://git.kernel.org/pub/scm/utils/dtc/dtc.git
You can decode a binary file with::
dtc -I dtb -O dts <filename.dtb>
That repo also includes `fdtget`/`fdtput` for reading and writing properties in
a binary file. U-Boot adds its own `fdtgrep` for creating subsets of the file.
Where do I get a devicetree file for my board?
----------------------------------------------
You may find that the Linux kernel has a suitable file. Look in the
kernel source in arch/<arch>/boot/dts.
If not you might find other boards with suitable files that you can
modify to your needs. Look in the board directories for files with a
.dts extension.
Failing that, you could write one from scratch yourself!
Configuration
-------------
Use::
#define CONFIG_DEFAULT_DEVICE_TREE "<name>"
to set the filename of the devicetree source. Then put your devicetree
file into::
arch/<arch>/dts/<name>.dts
This should include your CPU or SOC's devicetree file, placed in
`arch/<arch>/dts`, and then make any adjustments required using a u-boot-dtsi
file for your board.
If CONFIG_OF_EMBED is defined, then it will be picked up and built into
the U-Boot image (including u-boot.bin). This is suitable for debugging
and development only and is not recommended for production devices.
If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed
in u-boot.bin so you can still just flash u-boot,bin onto your board. If you are
using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
tree binary.
If CONFIG_OF_BOARD is defined, a board-specific routine will provide the
devicetree at runtime, for example if an earlier bootloader stage creates
it and passes it to U-Boot.
If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on
startup. This is only useful for sandbox. Use the -d flag to U-Boot to
specify the file to read, -D for the default and -T for the test devicetree,
used to run sandbox unit tests.
You cannot use more than one of these options at the same time.
To use a devicetree file that you have compiled yourself, pass
EXT_DTB=<filename> to 'make', as in::
make EXT_DTB=boot/am335x-boneblack-pubkey.dtb
Then U-Boot will copy that file to u-boot.dtb, put it in the .img file
if used, and u-boot-dtb.bin.
If you wish to put the fdt at a different address in memory, you can
define the "fdtcontroladdr" environment variable. This is the hex
address of the fdt binary blob, and will override either of the options.
Be aware that this environment variable is checked prior to relocation,
when only the compiled-in environment is available. Therefore it is not
possible to define this variable in the saved SPI/NAND flash
environment, for example (it will be ignored). After relocation, this
variable will be set to the address of the newly relocated fdt blob.
It is read-only and cannot be changed. It can optionally be used to
control the boot process of Linux with bootm/bootz commands.
To use this, put something like this in your board header file::
#define CONFIG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0"
Build:
After the board configuration is done, fdt supported u-boot can be built in two
ways:
# build the default dts which is defined from CONFIG_DEFAULT_DEVICE_TREE::
$ make
# build the user specified dts file::
$ make DEVICE_TREE=<dts-file-name>
.. _dttweaks:
Adding tweaks for U-Boot
------------------------
It is strongly recommended that devicetree files in U-Boot are an exact copy of
those in Linux, so that it is easy to sync them up from time to time.
U-Boot is of course a very different project from Linux, e.g. it operates under
much more restrictive memory and code-size constraints. Where Linux may use a
full clock driver with Common Clock Format (CCF) to find the input clock to the
UART, U-Boot typically wants to output a banner as early as possible before too
much code has run.
A second difference is that U-Boot includes different phases. For SPL,
constraints are even more extreme and the devicetree is shrunk to remove
unwanted nodes, or even turned into C code to avoid access overhead.
U-Boot automatically looks for and includes a file with updates to the standard
devicetree for your board, searching for them in the same directory as the
main file, in this order::
<orig_filename>-u-boot.dtsi
<CONFIG_SYS_SOC>-u-boot.dtsi
<CONFIG_SYS_CPU>-u-boot.dtsi
<CONFIG_SYS_VENDOR>-u-boot.dtsi
u-boot.dtsi
Only one of these is selected but of course you can #include another one within
that file, to create a hierarchy of shared files.
Relocation, SPL and TPL
-----------------------
U-Boot can be divided into three phases: TPL, SPL and U-Boot proper.
The full devicetree is available to U-Boot proper, but normally only a subset
(or none at all) is available to TPL and SPL. See 'Pre-Relocation Support' and
'SPL Support' in doc/driver-model/design.rst for more details.
Using several DTBs in the SPL (CONFIG_SPL_MULTI_DTB)
----------------------------------------------------
In some rare cases it is desirable to let SPL be able to select one DTB among
many. This usually not very useful as the DTB for the SPL is small and usually
fits several platforms. However the DTB sometimes include information that do
work on several platforms (like IO tuning parameters).
In this case it is possible to use CONFIG_SPL_MULTI_DTB. This option appends to
the SPL a FIT image containing several DTBs listed in SPL_OF_LIST.
board_fit_config_name_match() is called to select the right DTB.
If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM
containing the board ID for example), it possible to start with a generic DTB
and then switch over to the right DTB after the detection. For this purpose,
the platform code must call fdtdec_resetup(). Based on the returned flag, the
platform may have to re-initialise the DM subsystem using dm_uninit() and
dm_init_and_scan().
Limitations
-----------
Devicetrees can help reduce the complexity of supporting variants of boards
which use the same SOC / CPU.
However U-Boot is designed to build for a single architecture type and CPU
type. So for example it is not possible to build a single ARM binary
which runs on your AT91 and OMAP boards, relying on an fdt to configure
the various features. This is because you must select one of
the CPU families within arch/arm/cpu/arm926ejs (omap or at91) at build
time. Similarly U-Boot cannot be built for multiple cpu types or
architectures.
It is important to understand that the fdt only selects options
available in the platform / drivers. It cannot add new drivers (yet). So
you must still have the CONFIG option to enable the driver. For example,
you need to define CONFIG_SYS_NS16550 to bring in the NS16550 driver,
but can use the fdt to specific the UART clock, peripheral address, etc.
In very broad terms, the CONFIG options in general control *what* driver
files are pulled in, and the fdt controls *how* those files work.
History
-------
U-Boot configuration was previous done using CONFIG options in the board
config file. This eventually got out of hand with nearly 10,000 options.
U-Boot adopted devicetrees around the same time as Linux and early boards
used it before Linux (e.g. snow). The two projects developed in parallel
and there are still some differences in the bindings for certain boards.
While there has been discussion of having a separate repository for devicetree
files, in practice the Linux kernel Git repository has become the place where
these are stored, with U-Boot taking copies and adding tweaks with u-boot.dtsi
files.
.. _dtspec: https://www.devicetree.org/specifications/
.. _dtlist: https://www.spinics.net/lists/devicetree-compiler/

View file

@ -0,0 +1,13 @@
.. SPDX-License-Identifier: GPL-2.0+
Devicetree in U-Boot
====================
The following holds information on how U-Boot makes use of devicetree for
build-time and runtime configuration.
.. toctree::
:maxdepth: 2
intro
control

View file

@ -0,0 +1,44 @@
.. SPDX-License-Identifier: GPL-2.0+
Devicetree Introduction
=======================
U-Boot uses a devicetree for configuration. This includes the devices used by
the board, the format of the image created with binman, which UART to use for
the console, public keys used for secure boot and many other things.
See :doc:`control` for more information.
Why does U-Boot put <thing> in the devicetree?
----------------------------------------------
This question comes up a lot with people new to U-Boot, particular those coming
from Linux who are used to quite strict rules about what can go into the
devicetree.
U-Boot uses the same devicetree as Linux but adds more things necessary for the
bootloader environment (see :ref:`dttweaks`).
U-Boot does not have a user space to provide policy and configuration. It cannot
do what Linux does and run programs and look up filesystems to figure out how to
boot. So configuration and runtime information goes into the devicetree in
U-Boot.
Of course it is possible to:
- add tables into the rodata section of the U-Boot binary
- append some info to the end of U-Boot in a different format
- modify the linker script to bring in a file with some info in it
- put things in ACPI tables
- link in a UEFI hand-off block structure and put things in there
but *please don't*. In general, devicetree is the sane place to hold U-Boot's
configuration.
So, please, do NOT ask why U-Boot puts <thing> in the devicetree. It is the only
place it can go. It is a highly suitable data structure for just about anything
that U-Boot needs to know at runtime.
Note, it is possible to use platdata directly so drivers avoid devicetreee in
SPL. But of-platdata is the modern way of avoiding devicetree overhead, so
please use that instead.

View file

@ -11,6 +11,7 @@ Implementation
ci_testing
commands
devicetree/index
driver-model/index
global_data
logging

View file

@ -1,141 +0,0 @@
STMicroelectronics STM32 ADC device
STM32 ADC is a successive approximation analog-to-digital converter.
It has several multiplexed input channels. Conversions can be performed
in single, continuous, scan or discontinuous mode. Result of the ADC is
stored in a left-aligned or right-aligned 32-bit data register.
Conversions can be launched in software or using hardware triggers.
The analog watchdog feature allows the application to detect if the input
voltage goes beyond the user-defined, higher or lower thresholds.
Each STM32 ADC block can have up to 3 ADC instances.
Each instance supports two contexts to manage conversions, each one has its
own configurable sequence and trigger:
- regular conversion can be done in sequence, running in background
- injected conversions have higher priority, and so have the ability to
interrupt regular conversion sequence (either triggered in SW or HW).
Regular sequence is resumed, in case it has been interrupted.
Contents of a stm32 adc root node:
-----------------------------------
Required properties:
- compatible: Should be one of:
"st,stm32f4-adc-core"
"st,stm32h7-adc-core"
"st,stm32mp1-adc-core"
- reg: Offset and length of the ADC block register set.
- interrupts: One or more interrupts for ADC block. Some parts like stm32f4
and stm32h7 share a common ADC interrupt line. stm32mp1 has two separate
interrupt lines, one for each ADC within ADC block.
- clocks: Core can use up to two clocks, depending on part used:
- "adc" clock: for the analog circuitry, common to all ADCs.
It's required on stm32f4.
It's optional on stm32h7.
- "bus" clock: for registers access, common to all ADCs.
It's not present on stm32f4.
It's required on stm32h7.
- clock-names: Must be "adc" and/or "bus" depending on part used.
- interrupt-controller: Identifies the controller node as interrupt-parent
- vref-supply: Phandle to the vref input analog reference voltage.
- #interrupt-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
Optional properties:
- A pinctrl state named "default" for each ADC channel may be defined to set
inX ADC pins in mode of operation for analog input on external pin.
Contents of a stm32 adc child node:
-----------------------------------
An ADC block node should contain at least one subnode, representing an
ADC instance available on the machine.
Required properties:
- compatible: Should be one of:
"st,stm32f4-adc"
"st,stm32h7-adc"
"st,stm32mp1-adc"
- reg: Offset of ADC instance in ADC block (e.g. may be 0x0, 0x100, 0x200).
- clocks: Input clock private to this ADC instance. It's required only on
stm32f4, that has per instance clock input for registers access.
- interrupt-parent: Phandle to the parent interrupt controller.
- interrupts: IRQ Line for the ADC (e.g. may be 0 for adc@0, 1 for adc@100 or
2 for adc@200).
- st,adc-channels: List of single-ended channels muxed for this ADC.
It can have up to 16 channels on stm32f4 or 20 channels on stm32h7, numbered
from 0 to 15 or 19 (resp. for in0..in15 or in0..in19).
- st,adc-diff-channels: List of differential channels muxed for this ADC.
Depending on part used, some channels can be configured as differential
instead of single-ended (e.g. stm32h7). List here positive and negative
inputs pairs as <vinp vinn>, <vinp vinn>,... vinp and vinn are numbered
from 0 to 19 on stm32h7)
Note: At least one of "st,adc-channels" or "st,adc-diff-channels" is required.
Both properties can be used together. Some channels can be used as
single-ended and some other ones as differential (mixed). But channels
can't be configured both as single-ended and differential (invalid).
- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers" in
Documentation/devicetree/bindings/iio/iio-bindings.txt
Optional properties:
- dmas: Phandle to dma channel for this ADC instance.
See ../../dma/dma.txt for details.
- dma-names: Must be "rx" when dmas property is being used.
- assigned-resolution-bits: Resolution (bits) to use for conversions. Must
match device available resolutions:
* can be 6, 8, 10 or 12 on stm32f4
* can be 8, 10, 12, 14 or 16 on stm32h7
Default is maximum resolution if unset.
- st,min-sample-time-nsecs: Minimum sampling time in nanoseconds.
Depending on hardware (board) e.g. high/low analog input source impedance,
fine tune of ADC sampling time may be recommended.
This can be either one value or an array that matches 'st,adc-channels' list,
to set sample time resp. for all channels, or independently for each channel.
Example:
adc: adc@40012000 {
compatible = "st,stm32f4-adc-core";
reg = <0x40012000 0x400>;
interrupts = <18>;
clocks = <&rcc 0 168>;
clock-names = "adc";
vref-supply = <&reg_vref>;
interrupt-controller;
pinctrl-names = "default";
pinctrl-0 = <&adc3_in8_pin>;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "st,stm32f4-adc";
#io-channel-cells = <1>;
reg = <0x0>;
clocks = <&rcc 0 168>;
interrupt-parent = <&adc>;
interrupts = <0>;
st,adc-channels = <8>;
dmas = <&dma2 0 0 0x400 0x0>;
dma-names = "rx";
assigned-resolution-bits = <8>;
};
...
other adc child nodes follow...
};
Example to setup:
- channel 1 as single-ended
- channels 2 & 3 as differential (with resp. 6 & 7 negative inputs)
adc: adc@40022000 {
compatible = "st,stm32h7-adc-core";
...
adc1: adc@0 {
compatible = "st,stm32h7-adc";
...
st,adc-channels = <1>;
st,adc-diff-channels = <2 6>, <3 7>;
};
};

View file

@ -1,95 +0,0 @@
STMicroelectronics STM32 Reset and Clock Controller
===================================================
The RCC IP is both a reset and a clock controller.
Please refer to clock-bindings.txt for common clock controller binding usage.
Please also refer to reset.txt for common reset controller binding usage.
Required properties:
- compatible: Should be:
"st,stm32f42xx-rcc"
"st,stm32f469-rcc"
- reg: should be register base and length as documented in the
datasheet
- #reset-cells: 1, see below
- #clock-cells: 2, device nodes should specify the clock in their "clocks"
property, containing a phandle to the clock device node, an index selecting
between gated clocks and other clocks and an index specifying the clock to
use.
Example:
rcc: rcc@40023800 {
#reset-cells = <1>;
#clock-cells = <2>
compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
reg = <0x40023800 0x400>;
};
Specifying gated clocks
=======================
The primary index must be set to 0.
The secondary index is the bit number within the RCC register bank, starting
from the first RCC clock enable register (RCC_AHB1ENR, address offset 0x30).
It is calculated as: index = register_offset / 4 * 32 + bit_offset.
Where bit_offset is the bit offset within the register (LSB is 0, MSB is 31).
To simplify the usage and to share bit definition with the reset and clock
drivers of the RCC IP, macros are available to generate the index in
human-readble format.
For STM32F4 series, the macro are available here:
- include/dt-bindings/mfd/stm32f4-rcc.h
Example:
/* Gated clock, AHB1 bit 0 (GPIOA) */
... {
clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>
};
/* Gated clock, AHB2 bit 4 (CRYP) */
... {
clocks = <&rcc 0 STM32F4_AHB2_CLOCK(CRYP)>
};
Specifying other clocks
=======================
The primary index must be set to 1.
The secondary index is bound with the following magic numbers:
0 SYSTICK
1 FCLK
Example:
/* Misc clock, FCLK */
... {
clocks = <&rcc 1 STM32F4_APB1_CLOCK(TIM2)>
};
Specifying softreset control of devices
=======================================
Device nodes should specify the reset channel required in their "resets"
property, containing a phandle to the reset device node and an index specifying
which channel to use.
The index is the bit number within the RCC registers bank, starting from RCC
base address.
It is calculated as: index = register_offset / 4 * 32 + bit_offset.
Where bit_offset is the bit offset within the register.
For example, for CRC reset:
crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140
example:
timer2 {
resets = <&rcc STM32F4_APB1_RESET(TIM2)>;
};

View file

@ -1,152 +0,0 @@
STMicroelectronics STM32H7 Reset and Clock Controller
=====================================================
The RCC IP is both a reset and a clock controller.
Please refer to clock-bindings.txt for common clock controller binding usage.
Please also refer to reset.txt for common reset controller binding usage.
Required properties:
- compatible: Should be:
"st,stm32h743-rcc"
- reg: should be register base and length as documented in the
datasheet
- #reset-cells: 1, see below
- #clock-cells : from common clock binding; shall be set to 1
- clocks: External oscillator clock phandle
- high speed external clock signal (HSE)
- low speed external clock signal (LSE)
- external I2S clock (I2S_CKIN)
- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
write protection (RTC clock).
- pll x node: Allow to register a pll with specific parameters.
Please see PLL section below.
Example:
rcc: rcc@58024400 {
#reset-cells = <1>;
#clock-cells = <2>
compatible = "st,stm32h743-rcc", "st,stm32-rcc";
reg = <0x58024400 0x400>;
clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>;
st,syscfg = <&pwrcfg>;
#address-cells = <1>;
#size-cells = <0>;
vco1@58024430 {
#clock-cells = <0>;
compatible = "stm32,pll";
reg = <0>;
};
vco2@58024438 {
#clock-cells = <0>;
compatible = "stm32,pll";
reg = <1>;
st,clock-div = <2>;
st,clock-mult = <40>;
st,frac-status = <0>;
st,frac = <0>;
st,vcosel = <1>;
st,pllrge = <2>;
};
};
STM32H7 PLL
-----------
The VCO of STM32 PLL could be reprensented like this:
Vref --------- --------
---->| / DIVM |---->| x DIVN | ------> VCO
--------- --------
^
|
-------
| FRACN |
-------
When the PLL is configured in integer mode:
- VCO = ( Vref / DIVM ) * DIVN
When the PLL is configured in fractional mode:
- VCO = ( Vref / DIVM ) * ( DIVN + FRACN / 2^13)
Required properties for pll node:
- compatible: Should be:
"stm32,pll"
- #clock-cells: from common clock binding; shall be set to 0
- reg: Should be the pll number.
Optional properties:
- st,clock-div: DIVM division factor : <1..63>
- st,clock-mult: DIVN multiplication factor : <4..512>
- st,frac-status:
- 0 Pll is configured in integer mode
- 1 Pll is configure in fractional mode
- st,frac: Fractional part of the multiplication factor : <0..8191>
- st,vcosel: VCO selection
- 0: Wide VCO range:192 to 836 MHz
- 1: Medium VCO range:150 to 420 MHz
- st,pllrge: PLL input frequency range
- 0: The PLL input (Vref / DIVM) clock range frequency is between 1 and 2 MHz
- 1: The PLL input (Vref / DIVM) clock range frequency is between 2 and 4 MHz
- 2: The PLL input (Vref / DIVM) clock range frequency is between 4 and 8 MHz
- 3: The PLL input (Vref / DIVM) clock range frequency is between 8 and 16 MHz
The peripheral clock consumer should specify the desired clock by
having the clock ID in its "clocks" phandle cell.
All available clocks are defined as preprocessor macros in
dt-bindings/clock/stm32h7-clks.h header and can be used in device
tree sources.
Example:
timer5: timer@40000c00 {
compatible = "st,stm32-timer";
reg = <0x40000c00 0x400>;
interrupts = <50>;
clocks = <&rcc TIM5_CK>;
};
Specifying softreset control of devices
=======================================
Device nodes should specify the reset channel required in their "resets"
property, containing a phandle to the reset device node and an index specifying
which channel to use.
The index is the bit number within the RCC registers bank, starting from RCC
base address.
It is calculated as: index = register_offset / 4 * 32 + bit_offset.
Where bit_offset is the bit offset within the register.
For example, for CRC reset:
crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107
All available preprocessor macros for reset are defined dt-bindings//mfd/stm32h7-rcc.h
header and can be used in device tree sources.
example:
timer2 {
resets = <&rcc STM32H7_APB1L_RESET(TIM2)>;
};

View file

@ -1,30 +0,0 @@
* I2C controller embedded in STMicroelectronis STM32 platforms
Required properties :
- compatible : Must be "st,stm32f7-i2c"
- reg : Offset and length of the register set for the device
- resets: Must contain the phandle to the reset controller
- clocks: Must contain the input clock of the I2C instance
- A pinctrl state named "default" must be defined to set pins in mode of
operation for I2C transfer
- #address-cells = <1>;
- #size-cells = <0>;
Optional properties :
- clock-frequency : Desired I2C bus clock frequency in Hz. If not specified,
the default 100 kHz frequency will be used. As only Normal, Fast and Fast+
modes are implemented, possible values are 100000, 400000 and 1000000.
Example :
i2c1: i2c@40005400 {
compatible = "st,stm32f7-i2c";
reg = <0x40005400 0x400>;
resets = <&rcc 181>;
clocks = <&clk_pclk1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
};

View file

@ -1,58 +0,0 @@
ST, stm32 flexible memory controller Drive
Required properties:
- compatible : "st,stm32-fmc"
- reg : fmc controller base address
- clocks : fmc controller clock
u-boot,dm-pre-reloc: flag to initialize memory before relocation.
on-board sdram memory attributes:
- st,sdram-control : parameters for sdram configuration, in this order:
number of columns
number of rows
memory width
number of intenal banks in memory
cas latency
read burst enable or disable
read pipe delay
- st,sdram-timing: timings for sdram, in this order:
tmrd
txsr
tras
trc
trp
trcd
There is device tree include file at :
include/dt-bindings/memory/stm32-sdram.h to define sdram control and timing
parameters as MACROS.
Example:
fmc: fmc@A0000000 {
compatible = "st,stm32-fmc";
reg = <0xA0000000 0x1000>;
clocks = <&rcc 0 64>;
u-boot,dm-pre-reloc;
};
&fmc {
pinctrl-0 = <&fmc_pins>;
pinctrl-names = "default";
status = "okay";
/* sdram memory configuration from sdram datasheet */
bank1: bank@0 {
st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_2
CAS_3 RD_BURST_EN RD_PIPE_DL_0>;
st,sdram-timing = /bits/ 8 <TMRD_1 TXSR_60 TRAS_42 TRC_60 TRP_18
TRCD_18>;
};
/* sdram memory configuration from sdram datasheet */
bank2: bank@1 {
st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_2
CAS_3 RD_BURST_EN RD_PIPE_DL_0>;
st,sdram-timing = /bits/ 8 <TMRD_1 TXSR_60 TRAS_42 TRC_60 TRP_18
TRCD_18>;
};
}

View file

@ -1,61 +0,0 @@
STMicroelectronics Flexible Memory Controller 2 (FMC2)
NAND Interface
Required properties:
- compatible: Should be one of:
* st,stm32mp15-fmc2
- reg: NAND flash controller memory areas.
First region contains the register location.
Regions 2 to 4 respectively contain the data, command,
and address space for CS0.
Regions 5 to 7 contain the same areas for CS1.
- interrupts: The interrupt number
- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
- clocks: The clock needed by the NAND flash controller
Optional properties:
- resets: Reference to a reset controller asserting the FMC controller
- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
- dma-names: Must be "tx", "rx" and "ecc"
* NAND device bindings:
Required properties:
- reg: describes the CS lines assigned to the NAND device.
Optional properties:
- nand-on-flash-bbt: see nand.txt
- nand-ecc-strength: see nand.txt
- nand-ecc-step-size: see nand.txt
The following ECC strength and step size are currently supported:
- nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
- nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
- nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
Example:
fmc: nand-controller@58002000 {
compatible = "st,stm32mp15-fmc2";
reg = <0x58002000 0x1000>,
<0x80000000 0x1000>,
<0x88010000 0x1000>,
<0x88020000 0x1000>,
<0x81000000 0x1000>,
<0x89010000 0x1000>,
<0x89020000 0x1000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
pinctrl-names = "default";
pinctrl-0 = <&fmc_pins_a>;
#address-cells = <1>;
#size-cells = <0>;
nand@0 {
reg = <0>;
nand-on-flash-bbt;
#address-cells = <1>;
#size-cells = <1>;
};
};

View file

@ -1,75 +0,0 @@
STMicroelectronics STM32 USB HS PHY controller
The STM32 USBPHYC block contains a dual port High Speed UTMI+ PHY and a UTMI
switch. It controls PHY configuration and status, and the UTMI+ switch that
selects either OTG or HOST controller for the second PHY port. It also sets
PLL configuration.
USBPHYC
|_ PLL
|
|_ PHY port#1 _________________ HOST controller
| _ |
| / 1|________________|
|_ PHY port#2 ----| |________________
| \_0| |
|_ UTMI switch_______| OTG controller
Phy provider node
=================
Required properties:
- compatible: must be "st,stm32mp1-usbphyc"
- reg: address and length of the usb phy control register set
- clocks: phandle + clock specifier for the PLL phy clock
- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
- #address-cells: number of address cells for phys sub-nodes, must be <1>
- #size-cells: number of size cells for phys sub-nodes, must be <0>
Optional properties:
- assigned-clocks: phandle + clock specifier for the PLL phy clock
- assigned-clock-parents: the PLL phy clock parent
- resets: phandle + reset specifier
Required nodes: one sub-node per port the controller provides.
Phy sub-nodes
==============
Required properties:
- reg: phy port index
- phy-supply: phandle to the regulator providing 3V3 power to the PHY,
see phy-bindings.txt in the same directory.
- #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY
port#1 and must be <1> for PHY port#2, to select USB controller
Optional properties:
- vbus-supply: phandle to the regulator providing 5V vbus to the USB connector
Example:
usbphyc: usb-phy@5a006000 {
compatible = "st,stm32mp1-usbphyc";
reg = <0x5a006000 0x1000>;
clocks = <&rcc_clk USBPHY_K>;
resets = <&rcc_rst USBPHY_R>;
#address-cells = <1>;
#size-cells = <0>;
usbphyc_port0: usb-phy@0 {
reg = <0>;
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>
#phy-cells = <0>;
};
usbphyc_port1: usb-phy@1 {
reg = <1>;
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>
#phy-cells = <1>;
};
};

View file

@ -1,208 +0,0 @@
* STM32 GPIO and Pin Mux/Config controller
STMicroelectronics's STM32 MCUs intregrate a GPIO and Pin mux/config hardware
controller. It controls the input/output settings on the available pins and
also provides ability to multiplex and configure the output of various on-chip
controllers onto these pads.
Pin controller node:
Required properies:
- compatible: value should be one of the following:
"st,stm32f429-pinctrl"
"st,stm32f469-pinctrl"
"st,stm32f746-pinctrl"
"st,stm32f769-pinctrl"
"st,stm32h743-pinctrl"
"st,stm32mp157-pinctrl"
"st,stm32mp157-z-pinctrl"
- #address-cells: The value of this property must be 1
- #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to
gpio-bank node (children).
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
specify pins.
GPIO controller/bank node:
Required properties:
- gpio-controller : Indicates this device is a GPIO controller
- #gpio-cells : Should be two.
The first cell is the pin number
The second one is the polarity:
- 0 for active high
- 1 for active low
- reg : The gpio address range, relative to the pinctrl range
- clocks : clock that drives this bank
- st,bank-name : Should be a name string for this bank as specified in
the datasheet
Optional properties:
- reset: : Reference to the reset controller
- st,syscfg: Should be phandle/offset/mask.
-The phandle to the syscon node which includes IRQ mux selection register.
-The offset of the IRQ mux selection register
-The field mask of IRQ mux, needed if different of 0xf.
- gpio-ranges: Define a dedicated mapping between a pin-controller and
a gpio controller. Format is <&phandle a b c> with:
-(phandle): phandle of pin-controller.
-(a): gpio base offset in range.
-(b): pin base offset in range.
-(c): gpio count in range
This entry has to be used either if there are holes inside a bank:
GPIOB0/B1/B2/B14/B15 (see example 2)
or if banks are not contiguous:
GPIOA/B/C/E...
NOTE: If "gpio-ranges" is used for a gpio controller, all gpio-controller
have to use a "gpio-ranges" entry.
More details in Documentation/devicetree/bindings/gpio/gpio.txt.
- st,bank-ioport: should correspond to the EXTI IOport selection (EXTI line
used to select GPIOs as interrupts).
- hwlocks: reference to a phandle of a hardware spinlock provider node.
- st,package: Indicates the SOC package used.
More details in include/dt-bindings/pinctrl/stm32-pinfunc.h
Example 1:
#include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
...
pin-controller {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32f429-pinctrl";
ranges = <0 0x40020000 0x3000>;
pins-are-numbered;
gpioa: gpio@40020000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x400>;
resets = <&reset_ahb1 0>;
st,bank-name = "GPIOA";
};
...
pin-functions nodes follow...
};
Example 2:
#include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
...
pinctrl: pin-controller {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32f429-pinctrl";
ranges = <0 0x40020000 0x3000>;
pins-are-numbered;
gpioa: gpio@40020000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x400>;
resets = <&reset_ahb1 0>;
st,bank-name = "GPIOA";
gpio-ranges = <&pinctrl 0 0 16>;
};
gpiob: gpio@40020400 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x400>;
resets = <&reset_ahb1 0>;
st,bank-name = "GPIOB";
ngpios = 4;
gpio-ranges = <&pinctrl 0 16 3>,
<&pinctrl 14 30 2>;
};
...
pin-functions nodes follow...
};
Contents of function subnode node:
----------------------------------
Subnode format
A pinctrl node should contain at least one subnode representing the
pinctrl group available on the machine. Each subnode will list the
pins it needs, and how they should be configured, with regard to muxer
configuration, pullups, drive, output high/low and output speed.
node {
pinmux = <PIN_NUMBER_PINMUX>;
GENERIC_PINCONFIG;
};
Required properties:
- pinmux: integer array, represents gpio pin number and mux setting.
Supported pin number and mux varies for different SoCs, and are defined in
dt-bindings/pinctrl/<soc>-pinfunc.h directly.
These defines are calculated as:
((port * 16 + line) << 8) | function
With:
- port: The gpio port index (PA = 0, PB = 1, ..., PK = 11)
- line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15)
- function: The function number, can be:
* 0 : GPIO
* 1 : Alternate Function 0
* 2 : Alternate Function 1
* 3 : Alternate Function 2
* ...
* 16 : Alternate Function 15
* 17 : Analog
To simplify the usage, macro is available to generate "pinmux" field.
This macro is available here:
- include/dt-bindings/pinctrl/stm32-pinfunc.h
Some examples of using macro:
/* GPIO A9 set as alernate function 2 */
... {
pinmux = <STM32_PINMUX('A', 9, AF2)>;
};
/* GPIO A9 set as GPIO */
... {
pinmux = <STM32_PINMUX('A', 9, GPIO)>;
};
/* GPIO A9 set as analog */
... {
pinmux = <STM32_PINMUX('A', 9, ANALOG)>;
};
Optional properties:
- GENERIC_PINCONFIG: is the generic pinconfig options to use.
Available options are:
- bias-disable,
- bias-pull-down,
- bias-pull-up,
- drive-push-pull,
- drive-open-drain,
- output-low
- output-high
- slew-rate = <x>, with x being:
< 0 > : Low speed
< 1 > : Medium speed
< 2 > : Fast speed
< 3 > : High speed
Example:
pin-controller {
...
usart1_pins_a: usart1@0 {
pins1 {
pinmux = <STM32_PINMUX('A', 9, AF7)>;
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32_PINMUX('A', 10, AF7)>;
bias-disable;
};
};
};
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
};

View file

@ -1,23 +0,0 @@
STM32 VREFBUF - Voltage reference buffer
Some STM32 devices embed a voltage reference buffer which can be used as
voltage reference for ADCs, DACs and also as voltage reference for external
components through the dedicated VREF+ pin.
Required properties:
- compatible: Must be "st,stm32-vrefbuf".
- reg: Offset and length of VREFBUF register set.
- clocks: Must contain an entry for peripheral clock.
Optional properties:
- vdda-supply: Phandle to the parent vdda supply regulator node.
Example:
vrefbuf: regulator@58003c00 {
compatible = "st,stm32-vrefbuf";
reg = <0x58003C00 0x8>;
clocks = <&rcc VREF_CK>;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
vdda-supply = <&vdda>;
};

View file

@ -1,6 +0,0 @@
STMicroelectronics STM32 Peripheral Reset Controller
====================================================
The RCC IP is both a reset and a clock controller.
Please see Documentation/devicetree/bindings/clock/st,stm32-rcc.txt

View file

@ -1,44 +0,0 @@
* STMicroelectronics Quad Serial Peripheral Interface(QSPI)
Required properties:
- compatible: should be "st,stm32f469-qspi"
- reg: the first contains the register location and length.
the second contains the memory mapping address and length
- reg-names: should contain the reg names "qspi" "qspi_mm"
- interrupts: should contain the interrupt for the device
- clocks: the phandle of the clock needed by the QSPI controller
- A pinctrl must be defined to set pins in mode of operation for QSPI transfer
Optional properties:
- resets: must contain the phandle to the reset controller.
A spi flash (NOR/NAND) must be a child of spi node and could have some
properties. Also see jedec,spi-nor.txt.
Required properties:
- reg: chip-Select number (QSPI controller may connect 2 flashes)
- spi-max-frequency: max frequency of spi bus
Optional property:
- spi-rx-bus-width: see ./spi-bus.txt for the description
Example:
qspi: spi@a0001000 {
compatible = "st,stm32f469-qspi";
reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>;
reg-names = "qspi", "qspi_mm";
interrupts = <91>;
resets = <&rcc STM32F4_AHB3_RESET(QSPI)>;
clocks = <&rcc 0 STM32F4_AHB3_CLOCK(QSPI)>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi0>;
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-rx-bus-width = <4>;
spi-max-frequency = <108000000>;
...
};
};

View file

@ -37,18 +37,8 @@ import glob
from docutils import nodes, statemachine
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
#
# AutodocReporter is only good up to Sphinx 1.7
#
import sphinx
Use_SSI = sphinx.__version__[:3] >= '1.7'
if Use_SSI:
from sphinx.util.docutils import switch_source_input
else:
from sphinx.ext.autodoc import AutodocReporter
from sphinx.util.docutils import switch_source_input
import kernellog
__version__ = '1.0'
@ -163,18 +153,8 @@ class KernelDocDirective(Directive):
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
def do_parse(self, result, node):
if Use_SSI:
with switch_source_input(self.state, result):
self.state.nested_parse(result, 0, node, match_titles=1)
else:
save = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter)
self.state.memo.title_styles, self.state.memo.section_level = [], 0
try:
self.state.nested_parse(result, 0, node, match_titles=1)
finally:
self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = save
with switch_source_input(self.state, result):
self.state.nested_parse(result, 0, node, match_titles=1)
def setup(app):
app.add_config_value('kerneldoc_bin', None, 'env')

View file

@ -523,6 +523,7 @@ struct efi_device_path_acpi_path {
# define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f
# define DEVICE_PATH_SUB_TYPE_MSG_SATA 0x12
# define DEVICE_PATH_SUB_TYPE_MSG_NVME 0x17
# define DEVICE_PATH_SUB_TYPE_MSG_URI 0x18
# define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a
# define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d
@ -587,6 +588,11 @@ struct efi_device_path_nvme {
u8 eui64[8];
} __packed;
struct efi_device_path_uri {
struct efi_device_path dp;
u8 uri[];
} __packed;
#define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04
# define DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH 0x01
# define DEVICE_PATH_SUB_TYPE_CDROM_PATH 0x02

View file

@ -499,6 +499,11 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size);
efi_status_t efi_init_variables(void);
/* Notify ExitBootServices() is called */
void efi_variables_boot_exit_notify(void);
efi_status_t efi_tcg2_notify_exit_boot_services_failed(void);
/* Measure efi application invocation */
efi_status_t efi_tcg2_measure_efi_app_invocation(void);
/* Measure efi application exit */
efi_status_t efi_tcg2_measure_efi_app_exit(void);
/* Called by bootefi to initialize root node */
efi_status_t efi_root_node_register(void);
/* Called by bootefi to initialize runtime */

View file

@ -142,6 +142,26 @@ struct efi_tcg2_final_events_table {
struct tcg_pcr_event2 event[];
};
/**
* struct tdUEFI_VARIABLE_DATA - event log structure of UEFI variable
* @variable_name: The vendorGUID parameter in the
* GetVariable() API.
* @unicode_name_length: The length in CHAR16 of the Unicode name of
* the variable.
* @variable_data_length: The size of the variable data.
* @unicode_name: The CHAR16 unicode name of the variable
* without NULL-terminator.
* @variable_data: The data parameter of the efi variable
* in the GetVariable() API.
*/
struct efi_tcg2_uefi_variable_data {
efi_guid_t variable_name;
u64 unicode_name_length;
u64 variable_data_length;
u16 unicode_name[1];
u8 variable_data[1];
};
struct efi_tcg2_protocol {
efi_status_t (EFIAPI * get_capability)(struct efi_tcg2_protocol *this,
struct efi_tcg2_boot_service_capability *capability);

View file

@ -75,7 +75,7 @@ struct udevice;
/*
* event types, cf.
* "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
* rev 1.04, June 3, 2019
* Level 00 Version 1.05 Revision 23, May 7, 2021
*/
#define EV_EFI_EVENT_BASE ((u32)0x80000000)
#define EV_EFI_VARIABLE_DRIVER_CONFIG ((u32)0x80000001)
@ -87,8 +87,24 @@ struct udevice;
#define EV_EFI_ACTION ((u32)0x80000007)
#define EV_EFI_PLATFORM_FIRMWARE_BLOB ((u32)0x80000008)
#define EV_EFI_HANDOFF_TABLES ((u32)0x80000009)
#define EV_EFI_PLATFORM_FIRMWARE_BLOB2 ((u32)0x8000000A)
#define EV_EFI_HANDOFF_TABLES2 ((u32)0x8000000B)
#define EV_EFI_VARIABLE_BOOT2 ((u32)0x8000000C)
#define EV_EFI_HCRTM_EVENT ((u32)0x80000010)
#define EV_EFI_VARIABLE_AUTHORITY ((u32)0x800000E0)
#define EV_EFI_SPDM_FIRMWARE_BLOB ((u32)0x800000E1)
#define EV_EFI_SPDM_FIRMWARE_CONFIG ((u32)0x800000E2)
#define EFI_CALLING_EFI_APPLICATION \
"Calling EFI Application from Boot Option"
#define EFI_RETURNING_FROM_EFI_APPLICATION \
"Returning from EFI Application from Boot Option"
#define EFI_EXIT_BOOT_SERVICES_INVOCATION \
"Exit Boot Services Invocation"
#define EFI_EXIT_BOOT_SERVICES_FAILED \
"Exit Boot Services Returned with Failure"
#define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \
"Exit Boot Services Returned with Success"
/* TPMS_TAGGED_PROPERTY Structure */
struct tpms_tagged_property {

View file

@ -2182,6 +2182,11 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
efi_set_watchdog(0);
WATCHDOG_RESET();
out:
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
if (ret != EFI_SUCCESS)
efi_tcg2_notify_exit_boot_services_failed();
}
return EFI_EXIT(ret);
}
@ -2994,6 +2999,16 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
image_obj->exit_status = &exit_status;
image_obj->exit_jmp = &exit_jmp;
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
ret = efi_tcg2_measure_efi_app_invocation();
if (ret != EFI_SUCCESS) {
log_warning("tcg2 measurement fails(0x%lx)\n",
ret);
}
}
}
/* call the image! */
if (setjmp(&exit_jmp)) {
/*
@ -3252,6 +3267,16 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
exit_status != EFI_SUCCESS)
efi_delete_image(image_obj, loaded_image_protocol);
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
ret = efi_tcg2_measure_efi_app_exit();
if (ret != EFI_SUCCESS) {
log_warning("tcg2 measurement fails(0x%lx)\n",
ret);
}
}
}
/* Make sure entry/exit counts for EFI world cross-overs match */
EFI_EXIT(exit_status);

View file

@ -190,6 +190,19 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
break;
}
case DEVICE_PATH_SUB_TYPE_MSG_URI: {
struct efi_device_path_uri *udp =
(struct efi_device_path_uri *)dp;
int n;
n = (int)udp->dp.length - sizeof(struct efi_device_path_uri);
s += sprintf(s, "Uri(");
if (n > 0 && n < MAX_NODE_LEN - 6)
s += snprintf(s, n, "%s", (char *)udp->uri);
s += sprintf(s, ")");
break;
}
case DEVICE_PATH_SUB_TYPE_MSG_SD:
case DEVICE_PATH_SUB_TYPE_MSG_MMC: {
const char *typename =

View file

@ -35,6 +35,7 @@ struct event_log_buffer {
};
static struct event_log_buffer event_log;
static bool tcg2_efi_app_invoked;
/*
* When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset.
* Since the current tpm2_get_capability() response buffers starts at
@ -78,6 +79,19 @@ static const struct digest_info hash_algo_list[] = {
},
};
struct variable_info {
u16 *name;
const efi_guid_t *guid;
};
static struct variable_info secure_variables[] = {
{L"SecureBoot", &efi_global_variable_guid},
{L"PK", &efi_global_variable_guid},
{L"KEK", &efi_global_variable_guid},
{L"db", &efi_guid_image_security_database},
{L"dbx", &efi_guid_image_security_database},
};
#define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list)
/**
@ -1264,6 +1278,39 @@ free_pool:
return ret;
}
/**
* tcg2_measure_event() - common function to add event log and extend PCR
*
* @dev: TPM device
* @pcr_index: PCR index
* @event_type: type of event added
* @size: event size
* @event: event data
*
* Return: status code
*/
static efi_status_t
tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type,
u32 size, u8 event[])
{
struct tpml_digest_values digest_list;
efi_status_t ret;
ret = tcg2_create_digest(event, size, &digest_list);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
size, event);
out:
return ret;
}
/**
* efi_append_scrtm_version - Append an S-CRTM EV_S_CRTM_VERSION event on the
* eventlog and extend the PCRs
@ -1274,23 +1321,304 @@ free_pool:
*/
static efi_status_t efi_append_scrtm_version(struct udevice *dev)
{
struct tpml_digest_values digest_list;
u8 ver[] = U_BOOT_VERSION_STRING;
const int pcr_index = 0;
efi_status_t ret;
ret = tcg2_create_digest(ver, sizeof(ver), &digest_list);
ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION, sizeof(ver), ver);
return ret;
}
/**
* tcg2_measure_variable() - add variable event log and extend PCR
*
* @dev: TPM device
* @pcr_index: PCR index
* @event_type: type of event added
* @var_name: variable name
* @guid: guid
* @data_size: variable data size
* @data: variable data
*
* Return: status code
*/
static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index,
u32 event_type, u16 *var_name,
const efi_guid_t *guid,
efi_uintn_t data_size, u8 *data)
{
u32 event_size;
efi_status_t ret;
struct efi_tcg2_uefi_variable_data *event;
event_size = sizeof(event->variable_name) +
sizeof(event->unicode_name_length) +
sizeof(event->variable_data_length) +
(u16_strlen(var_name) * sizeof(u16)) + data_size;
event = malloc(event_size);
if (!event)
return EFI_OUT_OF_RESOURCES;
guidcpy(&event->variable_name, guid);
event->unicode_name_length = u16_strlen(var_name);
event->variable_data_length = data_size;
memcpy(event->unicode_name, var_name,
(event->unicode_name_length * sizeof(u16)));
if (data) {
memcpy((u16 *)event->unicode_name + event->unicode_name_length,
data, data_size);
}
ret = tcg2_measure_event(dev, pcr_index, event_type, event_size,
(u8 *)event);
free(event);
return ret;
}
/**
* tcg2_measure_boot_variable() - measure boot variables
*
* @dev: TPM device
*
* Return: status code
*/
static efi_status_t tcg2_measure_boot_variable(struct udevice *dev)
{
u16 *boot_order;
u16 *boot_index;
u16 var_name[] = L"BootOrder";
u16 boot_name[] = L"Boot####";
u8 *bootvar;
efi_uintn_t var_data_size;
u32 count, i;
efi_status_t ret;
boot_order = efi_get_var(var_name, &efi_global_variable_guid,
&var_data_size);
if (!boot_order) {
ret = EFI_NOT_FOUND;
goto error;
}
ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name,
&efi_global_variable_guid, var_data_size,
(u8 *)boot_order);
if (ret != EFI_SUCCESS)
goto error;
count = var_data_size / sizeof(*boot_order);
boot_index = boot_order;
for (i = 0; i < count; i++) {
efi_create_indexed_name(boot_name, sizeof(boot_name),
"Boot", *boot_index++);
bootvar = efi_get_var(boot_name, &efi_global_variable_guid,
&var_data_size);
if (!bootvar) {
log_info("%ls not found\n", boot_name);
continue;
}
ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2,
boot_name,
&efi_global_variable_guid,
var_data_size, bootvar);
free(bootvar);
if (ret != EFI_SUCCESS)
goto error;
}
error:
free(boot_order);
return ret;
}
/**
* efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
*
* Return: status code
*/
efi_status_t efi_tcg2_measure_efi_app_invocation(void)
{
efi_status_t ret;
u32 pcr_index;
struct udevice *dev;
u32 event = 0;
if (tcg2_efi_app_invoked)
return EFI_SUCCESS;
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS)
return ret;
ret = tcg2_measure_boot_variable(dev);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
strlen(EFI_CALLING_EFI_APPLICATION),
(u8 *)EFI_CALLING_EFI_APPLICATION);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_agile_log_append(pcr_index, EV_S_CRTM_VERSION, &digest_list,
sizeof(ver), ver);
for (pcr_index = 0; pcr_index <= 7; pcr_index++) {
ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR,
sizeof(event), (u8 *)&event);
if (ret != EFI_SUCCESS)
goto out;
}
tcg2_efi_app_invoked = true;
out:
return ret;
}
/**
* efi_tcg2_measure_efi_app_exit() - measure efi app exit
*
* Return: status code
*/
efi_status_t efi_tcg2_measure_efi_app_exit(void)
{
efi_status_t ret;
struct udevice *dev;
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS)
return ret;
ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
strlen(EFI_RETURNING_FROM_EFI_APPLICATION),
(u8 *)EFI_RETURNING_FROM_EFI_APPLICATION);
return ret;
}
/**
* efi_tcg2_notify_exit_boot_services() - ExitBootService callback
*
* @event: callback event
* @context: callback context
*/
static void EFIAPI
efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
{
efi_status_t ret;
struct udevice *dev;
EFI_ENTRY("%p, %p", event, context);
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
(u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_SUCCEEDED),
(u8 *)EFI_EXIT_BOOT_SERVICES_SUCCEEDED);
out:
EFI_EXIT(ret);
}
/**
* efi_tcg2_notify_exit_boot_services_failed()
* - notify ExitBootServices() is failed
*
* Return: status code
*/
efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
{
struct udevice *dev;
efi_status_t ret;
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
(u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_FAILED),
(u8 *)EFI_EXIT_BOOT_SERVICES_FAILED);
out:
return ret;
}
/**
* tcg2_measure_secure_boot_variable() - measure secure boot variables
*
* @dev: TPM device
*
* Return: status code
*/
static efi_status_t tcg2_measure_secure_boot_variable(struct udevice *dev)
{
u8 *data;
efi_uintn_t data_size;
u32 count, i;
efi_status_t ret;
count = ARRAY_SIZE(secure_variables);
for (i = 0; i < count; i++) {
/*
* According to the TCG2 PC Client PFP spec, "SecureBoot",
* "PK", "KEK", "db" and "dbx" variables must be measured
* even if they are empty.
*/
data = efi_get_var(secure_variables[i].name,
secure_variables[i].guid,
&data_size);
ret = tcg2_measure_variable(dev, 7,
EV_EFI_VARIABLE_DRIVER_CONFIG,
secure_variables[i].name,
secure_variables[i].guid,
data_size, data);
free(data);
if (ret != EFI_SUCCESS)
goto error;
}
/*
* TCG2 PC Client PFP spec says "dbt" and "dbr" are
* measured if present and not empty.
*/
data = efi_get_var(L"dbt",
&efi_guid_image_security_database,
&data_size);
if (data) {
ret = tcg2_measure_variable(dev, 7,
EV_EFI_VARIABLE_DRIVER_CONFIG,
L"dbt",
&efi_guid_image_security_database,
data_size, data);
free(data);
}
data = efi_get_var(L"dbr",
&efi_guid_image_security_database,
&data_size);
if (data) {
ret = tcg2_measure_variable(dev, 7,
EV_EFI_VARIABLE_DRIVER_CONFIG,
L"dbr",
&efi_guid_image_security_database,
data_size, data);
free(data);
}
error:
return ret;
}
@ -1305,6 +1633,7 @@ efi_status_t efi_tcg2_register(void)
{
efi_status_t ret = EFI_SUCCESS;
struct udevice *dev;
struct efi_event *event;
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS) {
@ -1328,6 +1657,21 @@ efi_status_t efi_tcg2_register(void)
tcg2_uninit();
goto fail;
}
ret = efi_create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
efi_tcg2_notify_exit_boot_services, NULL,
NULL, &event);
if (ret != EFI_SUCCESS) {
tcg2_uninit();
goto fail;
}
ret = tcg2_measure_secure_boot_variable(dev);
if (ret != EFI_SUCCESS) {
tcg2_uninit();
goto fail;
}
return ret;
fail: