From 5f6efc35c1a9e75725f95205905c0357a37e8b43 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 2 Aug 2021 22:10:04 +0200 Subject: [PATCH 01/13] doc: add pkg-config to the build dependencies tools/Makefile uses pkg-config. Signed-off-by: Heinrich Schuchardt --- doc/build/gcc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index e03e0b9460..0cdc307d57 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -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 From b2a1d6b2c48c549d3a7c1f9c465ac9da7edf9a3b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 5 Aug 2021 20:13:41 +0200 Subject: [PATCH 02/13] doc: require Sphinx 2.4.4 Require Sphinx 2.44 to build the documentation. Remove all code related to earlier versions. Signed-off-by: Heinrich Schuchardt --- doc/conf.py | 77 ++--------------------------------------- doc/sphinx/kerneldoc.py | 26 ++------------ 2 files changed, 5 insertions(+), 98 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index eb74b86aef..dae6231907 100644 --- a/doc/conf.py +++ b/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'] @@ -380,72 +373,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} diff --git a/doc/sphinx/kerneldoc.py b/doc/sphinx/kerneldoc.py index e9857ab904..8189c33b9d 100644 --- a/doc/sphinx/kerneldoc.py +++ b/doc/sphinx/kerneldoc.py @@ -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') From 00e80da9f5e9a98d3234efac2149cc5936ea2c74 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 5 Aug 2021 20:18:06 +0200 Subject: [PATCH 03/13] doc: fix Latex margins Adjust the Latex formatting to match Linux v5.13.1: * add Latex margins * reformat the code in doc/conf.py to match Linux Signed-off-by: Heinrich Schuchardt --- doc/conf.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index dae6231907..eac3accd56 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -338,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 From 3e9fddfc4f146f3a64c935024f5e1918790d2777 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Aug 2021 18:57:10 -0600 Subject: [PATCH 04/13] doc: Move devicetree control doc to rST Move this to rST format, largely unchanged to start with. Add an index for this topic, as well as an empty intro. Note this patch does not include updates! Is it just a conversion to the new format. See the next patch. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchart --- .../devicetree/control.rst} | 50 +++++++++---------- doc/develop/devicetree/index.rst | 13 +++++ doc/develop/devicetree/intro.rst | 4 ++ doc/develop/index.rst | 1 + 4 files changed, 43 insertions(+), 25 deletions(-) rename doc/{README.fdt-control => develop/devicetree/control.rst} (89%) create mode 100644 doc/develop/devicetree/index.rst create mode 100644 doc/develop/devicetree/intro.rst diff --git a/doc/README.fdt-control b/doc/develop/devicetree/control.rst similarity index 89% rename from doc/README.fdt-control rename to doc/develop/devicetree/control.rst index 424d13fc5b..1289b6156f 100644 --- a/doc/README.fdt-control +++ b/doc/develop/devicetree/control.rst @@ -1,6 +1,5 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright (c) 2011 The Chromium OS Authors. +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Copyright 2011 The Chromium OS Authors Device Tree Control in U-Boot ============================= @@ -37,9 +36,7 @@ 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 +the fdt syntax, take a look at the specification (dtspec_). You also might find this section of the Linux kernel documentation useful: (access this in the Linux kernel source code) @@ -60,18 +57,18 @@ 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: +If you want to build your own dtc, it is kept here:: git://git.kernel.org/pub/scm/utils/dtc/dtc.git -For example: +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): +Then run the compiler (your version will vary):: $ dtc -v Version: DTC 1.2.0-g2cb4b51f @@ -105,14 +102,14 @@ Failing that, you could write one from scratch yourself! Configuration ------------- -Use: +Use:: -#define CONFIG_DEFAULT_DEVICE_TREE "" + #define CONFIG_DEFAULT_DEVICE_TREE "" to set the filename of the device tree source. Then put your device tree -file into +file into:: - board//dts/.dts + board//dts/.dts This should include your CPU or SOC's device tree file, placed in arch//dts, and then make any adjustments required. @@ -123,9 +120,9 @@ 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: +join the two:: - cat u-boot-nodtb.bin u-boot.dtb >image.bin + 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 @@ -144,9 +141,9 @@ 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= to 'make', as in: +EXT_DTB= to 'make', as in:: - make EXT_DTB=boot/am335x-boneblack-pubkey.dtb + 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. @@ -162,16 +159,21 @@ 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: +To use this, put something like this in your board header file:: -#define CONFIG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0" + #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 +After board configuration is done, fdt supported u-boot can be build in two +ways: + +# build the default dts which is defined from CONFIG_DEFAULT_DEVICE_TREE:: + $ make -2) build the user specified dts file + +# build the user specified dts file:: + $ make DEVICE_TREE= @@ -225,6 +227,4 @@ 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 -1-Sep-11 +.. _dtspec: https://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst new file mode 100644 index 0000000000..fa5db3eb76 --- /dev/null +++ b/doc/develop/devicetree/index.rst @@ -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 diff --git a/doc/develop/devicetree/intro.rst b/doc/develop/devicetree/intro.rst new file mode 100644 index 0000000000..344851327c --- /dev/null +++ b/doc/develop/devicetree/intro.rst @@ -0,0 +1,4 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Devicetree Introduction +======================= diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 1203409db7..83c929babd 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -11,6 +11,7 @@ Implementation ci_testing commands + devicetree/index driver-model/index global_data logging From 5edf62c3003fdd3755367b52cccacbd3a7aa84d0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Aug 2021 18:57:11 -0600 Subject: [PATCH 05/13] doc: Update devicedocs including how to add tweaks This file is about 10 years old and the updates have not covered everything that has changed, particularly in the last few years. Update the information and add mention of the u-boot.dtsi files. Signed-off-by: Simon Glass Fix typos. Reviewed-by: Heinrich Schuchardt --- doc/develop/devicetree/control.rst | 181 ++++++++++++++++------------- 1 file changed, 100 insertions(+), 81 deletions(-) diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst index 1289b6156f..f330975a8f 100644 --- a/doc/develop/devicetree/control.rst +++ b/doc/develop/devicetree/control.rst @@ -1,93 +1,72 @@ .. SPDX-License-Identifier: GPL-2.0+ .. sectionauthor:: Copyright 2011 The Chromium OS Authors -Device Tree Control in U-Boot -============================= +Devicetree 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. +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. 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. +for three reasons: -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. +- 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 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 +The 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 device tree file, and have a single +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 Flat Device Tree? ---------------------------- +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_). -You also might find this section of the Linux kernel documentation -useful: (access this in the Linux kernel source code) +There is also a mailing list (dtlist_) for the compiler and associated +tools. - 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. +In case you are wondering, OF stands for Open Firmware. This follows the +convention used in Linux. Tools ----- -To use this feature you will need to get the device tree compiler. This is +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), it is currently not used. +(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 + git://git.kernel.org/pub/scm/utils/dtc/dtc.git -For example:: +You can decode a binary file with:: - $ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git - $ cd dtc - $ make - $ sudo make install + dtc -I dtb -O dts -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. +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 an fdt file for my board? ----------------------------------------- +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//boot/dts. @@ -106,41 +85,37 @@ Use:: #define CONFIG_DEFAULT_DEVICE_TREE "" -to set the filename of the device tree source. Then put your device tree +to set the filename of the devicetree source. Then put your devicetree file into:: - board//dts/.dts + arch//dts/.dts -This should include your CPU or SOC's device tree file, placed in -arch//dts, and then make any adjustments required. +This should include your CPU or SOC's devicetree file, placed in +`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. 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 +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 -device tree at runtime, for example if an earlier bootloader stage creates +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. +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 device tree file that you have compiled yourself, pass +To use a devicetree file that you have compiled yourself, pass EXT_DTB= to 'make', as in:: make EXT_DTB=boot/am335x-boneblack-pubkey.dtb @@ -165,7 +140,7 @@ To use this, put something like this in your board header file:: Build: -After board configuration is done, fdt supported u-boot can be build in two +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:: @@ -177,12 +152,41 @@ ways: $ make DEVICE_TREE= +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:: + + -u-boot.dtsi + -u-boot.dtsi + -u-boot.dtsi + -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 device tree is available to U-Boot proper, but normally only a subset +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. @@ -201,24 +205,24 @@ 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 +platform may have to re-initialise the DM subsystem using dm_uninit() and dm_init_and_scan(). Limitations ----------- -U-Boot is designed to build with a single architecture type and CPU +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 you cannot build for multiple cpu types or +time. Similarly U-Boot cannot be built 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, @@ -227,4 +231,19 @@ 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. -.. _dtspec: https://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf +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/ From 6a055c0f91418b78949b901147a63f2a4e26c9ab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Aug 2021 18:57:12 -0600 Subject: [PATCH 06/13] doc: Add a note about why devicetree is used This question comes up every now and then with people coming from Linux. Add some notes about it so we can point to it in the mailing list. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- doc/develop/devicetree/control.rst | 2 ++ doc/develop/devicetree/intro.rst | 40 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst index f330975a8f..e84dfb6677 100644 --- a/doc/develop/devicetree/control.rst +++ b/doc/develop/devicetree/control.rst @@ -152,6 +152,8 @@ ways: $ make DEVICE_TREE= +.. _dttweaks: + Adding tweaks for U-Boot ------------------------ diff --git a/doc/develop/devicetree/intro.rst b/doc/develop/devicetree/intro.rst index 344851327c..36e8cc0d44 100644 --- a/doc/develop/devicetree/intro.rst +++ b/doc/develop/devicetree/intro.rst @@ -2,3 +2,43 @@ 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 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 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. From 551a959a8c11e7f3452e0c2f24db85dffebc1e91 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 2 Aug 2021 18:08:36 +0200 Subject: [PATCH 07/13] doc: stm32mp1: add page for device tree bindings With device tree binding migration to yaml it is difficult to synchronize the binding from Linux kernel to U-Boot. Instead of maintaining the same dt bindings, this patch adds in the U-Boot documentation the path to the device tree bindings in Linux kernel for STMicroelectronics devices, when they are used without modification. Signed-off-by: Patrick Delaunay Signed-off-by: Patrice Chotard Add links for referenced text files. Signed-off-by: Heinrich Schuchardt --- doc/board/st/index.rst | 1 + doc/board/st/st.rst | 68 ++++++ doc/device-tree-bindings/adc/st,stm32-adc.txt | 141 ------------ .../clock/st,stm32-rcc.txt | 95 -------- .../clock/st,stm32h7-rcc.txt | 152 ------------- doc/device-tree-bindings/i2c/i2c-stm32.txt | 30 --- .../memory-controllers/st,stm32-fmc.txt | 58 ----- .../mtd/stm32-fmc2-nand.txt | 61 ----- .../phy/phy-stm32-usbphyc.txt | 75 ------- .../pinctrl/st,stm32-pinctrl.txt | 208 ------------------ .../regulator/st,stm32-vrefbuf.txt | 23 -- .../reset/st,stm32-rcc.txt | 6 - .../spi/spi-stm32-qspi.txt | 44 ---- 13 files changed, 69 insertions(+), 893 deletions(-) create mode 100644 doc/board/st/st.rst delete mode 100644 doc/device-tree-bindings/adc/st,stm32-adc.txt delete mode 100644 doc/device-tree-bindings/clock/st,stm32-rcc.txt delete mode 100644 doc/device-tree-bindings/clock/st,stm32h7-rcc.txt delete mode 100644 doc/device-tree-bindings/i2c/i2c-stm32.txt delete mode 100644 doc/device-tree-bindings/memory-controllers/st,stm32-fmc.txt delete mode 100644 doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt delete mode 100644 doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt delete mode 100644 doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt delete mode 100644 doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt delete mode 100644 doc/device-tree-bindings/reset/st,stm32-rcc.txt delete mode 100644 doc/device-tree-bindings/spi/spi-stm32-qspi.txt diff --git a/doc/board/st/index.rst b/doc/board/st/index.rst index 91f1d51b42..8a06a954a2 100644 --- a/doc/board/st/index.rst +++ b/doc/board/st/index.rst @@ -6,4 +6,5 @@ STMicroelectronics .. toctree:: :maxdepth: 2 + st stm32mp1 diff --git a/doc/board/st/st.rst b/doc/board/st/st.rst new file mode 100644 index 0000000000..3dade1681f --- /dev/null +++ b/doc/board/st/st.rst @@ -0,0 +1,68 @@ +.. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +.. sectionauthor:: Patrick Delaunay + +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 diff --git a/doc/device-tree-bindings/adc/st,stm32-adc.txt b/doc/device-tree-bindings/adc/st,stm32-adc.txt deleted file mode 100644 index 07fb6cd76b..0000000000 --- a/doc/device-tree-bindings/adc/st,stm32-adc.txt +++ /dev/null @@ -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 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>; - }; - }; diff --git a/doc/device-tree-bindings/clock/st,stm32-rcc.txt b/doc/device-tree-bindings/clock/st,stm32-rcc.txt deleted file mode 100644 index 0532d815da..0000000000 --- a/doc/device-tree-bindings/clock/st,stm32-rcc.txt +++ /dev/null @@ -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)>; - }; diff --git a/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt b/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt deleted file mode 100644 index 9d4b5873d9..0000000000 --- a/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt +++ /dev/null @@ -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)>; - }; diff --git a/doc/device-tree-bindings/i2c/i2c-stm32.txt b/doc/device-tree-bindings/i2c/i2c-stm32.txt deleted file mode 100644 index df03743ace..0000000000 --- a/doc/device-tree-bindings/i2c/i2c-stm32.txt +++ /dev/null @@ -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>; - }; diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32-fmc.txt b/doc/device-tree-bindings/memory-controllers/st,stm32-fmc.txt deleted file mode 100644 index 99f76d515f..0000000000 --- a/doc/device-tree-bindings/memory-controllers/st,stm32-fmc.txt +++ /dev/null @@ -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 ; - st,sdram-timing = /bits/ 8 ; - }; - - /* sdram memory configuration from sdram datasheet */ - bank2: bank@1 { - st,sdram-control = /bits/ 8 ; - st,sdram-timing = /bits/ 8 ; - }; - } diff --git a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt deleted file mode 100644 index ad2bef8265..0000000000 --- a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt +++ /dev/null @@ -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 = ; - 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>; - }; - }; diff --git a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt deleted file mode 100644 index edfe4b426c..0000000000 --- a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt +++ /dev/null @@ -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>; - }; - }; diff --git a/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt b/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt deleted file mode 100644 index 00169255e4..0000000000 --- a/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt +++ /dev/null @@ -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 -... - - 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 -... - - 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 = ; - 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/-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 = ; - }; - /* GPIO A9 set as GPIO */ - ... { - pinmux = ; - }; - /* GPIO A9 set as analog */ - ... { - pinmux = ; - }; - -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 = , 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 = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; - bias-disable; - }; - }; -}; - -&usart1 { - pinctrl-0 = <&usart1_pins_a>; - pinctrl-names = "default"; -}; diff --git a/doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt b/doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt deleted file mode 100644 index 0f6b6feda3..0000000000 --- a/doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt +++ /dev/null @@ -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>; - }; diff --git a/doc/device-tree-bindings/reset/st,stm32-rcc.txt b/doc/device-tree-bindings/reset/st,stm32-rcc.txt deleted file mode 100644 index 01db343751..0000000000 --- a/doc/device-tree-bindings/reset/st,stm32-rcc.txt +++ /dev/null @@ -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 diff --git a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt deleted file mode 100644 index adeeb63e84..0000000000 --- a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt +++ /dev/null @@ -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>; - ... - }; -}; From 148ce20520760d17f1d9db23c0575ffeed60a287 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 5 Aug 2021 21:10:05 +0000 Subject: [PATCH 08/13] efi_loader: Uri() device path node iPXE used Uri() device path nodes. So we should support them in the device path to text protocol. Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 6 ++++++ lib/efi_loader/efi_device_path_to_text.c | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/efi_api.h b/include/efi_api.h index e854a8b3a1..38ac47f164 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -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 diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 675e80bcb8..d46327a1c9 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -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 = From 17a50bd689ab7e506c71df0856fed5935cf323d1 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 28 May 2021 22:24:37 +0200 Subject: [PATCH 09/13] efi_loader: add Linux magic to RISC-V crt0 Add the Linux magic to the EFI file header to allow running our test programs with GRUB's linux command. MajorImageVersion = 1 indicates a kernel that can consume the EFI_LOAD_FILE2_PROTOCOL. This allows to dump the GRUB provided intird with our initrddump.efi tool. Signed-off-by: Heinrich Schuchardt --- arch/riscv/lib/crt0_riscv_efi.S | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index e7c4d99c21..b0a7a39a72 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -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 */ From cfbcf054a323b692e85e73fc2a57400ee92f6b63 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Fri, 13 Aug 2021 16:12:39 +0900 Subject: [PATCH 10/13] efi_loader: add secure boot variable measurement TCG PC Client PFP spec requires to measure the secure boot policy before validating the UEFI image. This commit adds the secure boot variable measurement of "SecureBoot", "PK", "KEK", "db", "dbx", "dbt", and "dbr". Note that this implementation assumes that secure boot variables are pre-configured and not be set/updated in runtime. Signed-off-by: Masahisa Kojima --- include/efi_tcg2.h | 20 +++++ lib/efi_loader/efi_tcg2.c | 165 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index bcfb98168a..497ba3ce94 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -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); diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 1319a8b378..db3d6d7586 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -78,6 +78,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 +1277,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 @@ -1294,6 +1340,118 @@ out: 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_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; +} + /** * efi_tcg2_register() - register EFI_TCG2_PROTOCOL * @@ -1328,6 +1486,13 @@ efi_status_t efi_tcg2_register(void) tcg2_uninit(); goto fail; } + + ret = tcg2_measure_secure_boot_variable(dev); + if (ret != EFI_SUCCESS) { + tcg2_uninit(); + goto fail; + } + return ret; fail: From 8fc4e0b4273adc741dfd1917970162ca224f98bf Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Fri, 13 Aug 2021 16:12:40 +0900 Subject: [PATCH 11/13] efi_loader: add boot variable measurement TCG PC Client PFP spec requires to measure "Boot####" and "BootOrder" variables, EV_SEPARATOR event prior to the Ready to Boot invocation. Since u-boot does not implement Ready to Boot event, these measurements are performed when efi_start_image() is called. TCG spec also requires to measure "Calling EFI Application from Boot Option" for each boot attempt, and "Returning from EFI Application from Boot Option" if a boot device returns control back to the Boot Manager. Signed-off-by: Masahisa Kojima --- include/efi_loader.h | 4 ++ include/tpm-v2.h | 18 ++++- lib/efi_loader/efi_boottime.c | 20 ++++++ lib/efi_loader/efi_tcg2.c | 121 ++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index a120d94431..6f61e9faac 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -499,6 +499,10 @@ 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); +/* 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 */ diff --git a/include/tpm-v2.h b/include/tpm-v2.h index 949a13c917..13b3db67c6 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -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 { diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 0b98e91813..13ab139222 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2994,6 +2994,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 +3262,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); diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index db3d6d7586..ed71337780 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -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 @@ -1385,6 +1386,126 @@ static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index, 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_measure_event(dev, 4, EV_EFI_ACTION, + strlen(EFI_CALLING_EFI_APPLICATION), + (u8 *)EFI_CALLING_EFI_APPLICATION); + if (ret != EFI_SUCCESS) + goto out; + + 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; +} + /** * tcg2_measure_secure_boot_variable() - measure secure boot variables * From fdff03e5b338772b9340b7b2965b9de71c323f24 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Fri, 13 Aug 2021 16:12:41 +0900 Subject: [PATCH 12/13] efi_loader: add ExitBootServices() measurement TCG PC Client PFP spec requires to measure "Exit Boot Services Invocation" if ExitBootServices() is invoked. Depending upon the return code from the ExitBootServices() call, "Exit Boot Services Returned with Success" or "Exit Boot Services Returned with Failure" is also measured. Signed-off-by: Masahisa Kojima Swap two ifs in efi_exit_boot_services(). efi_tcg2_notify_exit_boot_services must have EFIAPI signature. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 1 + lib/efi_loader/efi_boottime.c | 5 +++ lib/efi_loader/efi_tcg2.c | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/include/efi_loader.h b/include/efi_loader.h index 6f61e9faac..32cb8d0f1e 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -499,6 +499,7 @@ 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 */ diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 13ab139222..f0283b539e 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -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); } diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index ed71337780..c6f2e48106 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -1506,6 +1506,67 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void) 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 * @@ -1584,6 +1645,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) { @@ -1608,6 +1670,14 @@ efi_status_t efi_tcg2_register(void) 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(); From 61ee780352e054df587d8781f23b323c967b5d2a Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Fri, 13 Aug 2021 16:12:42 +0900 Subject: [PATCH 13/13] efi_loader: refactor efi_append_scrtm_version() Refactor efi_append_scrtm_version() to use common function for adding eventlog and extending PCR. Signed-off-by: Masahisa Kojima --- lib/efi_loader/efi_tcg2.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index c6f2e48106..35e69b9112 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -1321,23 +1321,11 @@ out: */ 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); - if (ret != EFI_SUCCESS) - goto out; + ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION, sizeof(ver), ver); - ret = tcg2_pcr_extend(dev, pcr_index, &digest_list); - if (ret != EFI_SUCCESS) - goto out; - - ret = tcg2_agile_log_append(pcr_index, EV_S_CRTM_VERSION, &digest_list, - sizeof(ver), ver); - -out: return ret; }