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:
commit
fdc4fda330
29 changed files with 845 additions and 1244 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -6,4 +6,5 @@ STMicroelectronics
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
st
|
||||
stm32mp1
|
||||
|
|
68
doc/board/st/st.rst
Normal file
68
doc/board/st/st.rst
Normal 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
4
doc/build/gcc.rst
vendored
|
@ -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
|
||||
|
||||
|
|
108
doc/conf.py
108
doc/conf.py
|
@ -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}
|
||||
|
|
251
doc/develop/devicetree/control.rst
Normal file
251
doc/develop/devicetree/control.rst
Normal 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/
|
13
doc/develop/devicetree/index.rst
Normal file
13
doc/develop/devicetree/index.rst
Normal 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
|
44
doc/develop/devicetree/intro.rst
Normal file
44
doc/develop/devicetree/intro.rst
Normal 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.
|
|
@ -11,6 +11,7 @@ Implementation
|
|||
|
||||
ci_testing
|
||||
commands
|
||||
devicetree/index
|
||||
driver-model/index
|
||||
global_data
|
||||
logging
|
||||
|
|
|
@ -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 = <®_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>;
|
||||
};
|
||||
};
|
|
@ -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)>;
|
||||
};
|
|
@ -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)>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
||||
}
|
|
@ -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>;
|
||||
};
|
||||
};
|
|
@ -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 = <®11>;
|
||||
vdda1v8-supply = <®18>
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usbphyc_port1: usb-phy@1 {
|
||||
reg = <1>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
vdda1v1-supply = <®11>;
|
||||
vdda1v8-supply = <®18>
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
};
|
|
@ -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";
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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
|
|
@ -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>;
|
||||
...
|
||||
};
|
||||
};
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue