From 46620d21a65f2af6f1fb8a82b3c10186d9bc02b3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 20 Dec 2021 18:12:04 +0000 Subject: [PATCH 01/28] doc: add Arm Juno board documentation The Juno Arm development board is an open, vendor-neutral, Armv8-A development platform. Add documentation that briefly outlines the hardware, and describes building and installation of U-Boot. Signed-off-by: Andre Przywara Reviewed-by: Sudeep Holla Reviewed-by: Linus Walleij Reviewed-by: Simon Glass --- doc/board/armltd/index.rst | 1 + doc/board/armltd/juno.rst | 114 +++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 doc/board/armltd/juno.rst diff --git a/doc/board/armltd/index.rst b/doc/board/armltd/index.rst index c20d8a0a26..fc1d75aac2 100644 --- a/doc/board/armltd/index.rst +++ b/doc/board/armltd/index.rst @@ -6,4 +6,5 @@ Arm Ltd .. toctree:: :maxdepth: 2 + juno vexpress64.rst diff --git a/doc/board/armltd/juno.rst b/doc/board/armltd/juno.rst new file mode 100644 index 0000000000..761c037f92 --- /dev/null +++ b/doc/board/armltd/juno.rst @@ -0,0 +1,114 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. Copyright (C) 2021 Arm Ltd. + +Arm Juno development platform +============================= + +The `Juno development board`_ is an open, vendor-neutral, Armv8-A development +platform, made by Arm Ltd. It is part of the Versatile Express family. +There are three revisions of the board: + +* Juno r0, with two Cortex-A57 and four Cortex-A53 cores, without PCIe. +* Juno r1, with two Cortex-A57 and four Cortex-A53 cores, in later silicon + revisions, and with PCIe slots, Gigabit Ethernet and two SATA ports. +* Juno r2, with two Cortex-A72 and four Cortex-A53 cores, otherwise the + same as r1. + +Among other things, the motherboard contains a management controller (MCC), +an FPGA providing I/O interfaces (IOFPGA) and 64MB of NOR flash. The provided +platform devices resemble the VExpress peripherals. +The actual SoC also contains a Cortex-M3 based System Control Processor (SCP). +The `V2M-Juno TRM`_ contains more technical details. + +U-Boot build +------------ +There is only one defconfig and one binary build that covers all three board +revisions, so to generate the needed ``u-boot.bin``: + +.. code-block:: bash + + $ make vexpress_aemv8a_juno_defconfig + $ make + +The automatic distro boot sequence looks for UEFI boot applications and +``boot.scr`` scripts on various boot media, starting with USB, then on disks +connected to the two SATA ports, PXE, DHCP and eventually on the NOR flash. + +U-Boot installation +------------------- +This assumes there is some firmware on the SD card or NOR flash (see below +for more details). The U-Boot binary is included in the Trusted Firmware +FIP image, so after building U-Boot, this needs to be repackaged or recompiled. + +The NOR flash will be updated by the MCC, based on the content of a micro-SD +card, which is exported as a USB mass storage device via the rear USB-B +socket. So to access that SD card, connect a cable to some host computer, and +mount the FAT16 partition of the UMS device. +If there is no device, check the upper serial port for a prompt, and +explicitly enable the USB interface:: + + Cmd> usb_on + Enabling debug USB... + +Repackaging an existing FIP image +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To prevent problems, it is probably a good idea to backup the existing firmware, +for instance by just copying the entire ``SOFTWARE/`` directory, or at least +the current ``fip.bin``, beforehand. + +To just replace the BL33 image in the exising FIP image, you can use +`fiptool`_ from the Trusted Firmware repository, on the image file: + +.. code-block:: bash + + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git + cd trusted-firmware-a + make fiptool + tools/fiptool/fiptool update --nt-fw=/path/to/your/u-boot.bin /mnt/juno/SOFTWARE/fip.bin + +Unmount the USB mass storage device and reboot the board, the new ``fip.bin`` +will be automatically written to the NOR flash and then used. + +Rebuilding Trusted Firmware +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +You can also generate a new FIP image by compiling Arm Trusted Firmware, +and providing ``u-boot.bin`` as the BL33 file. For that you can either build +the required `SCP firmware`_ yourself, or just extract the existing +version from your ``fip.bin``, using `fiptool`_ (see above): + +.. code-block:: bash + + mkdir /tmp/juno; cd /tmp/juno + fiptool unpack /mnt/juno/SOFTWARE/fip.bin + +Then build TF-A: + +.. code-block:: bash + + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git + cd trusted-firmware-a + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=juno DEBUG=1 \ + SCP_BL2=/tmp/juno/scp-fw.bin BL33=/path/to/your/u-boot.bin fiptool all fip + cp build/juno/debug/bl1.bin build/juno/debug/fip.bin /mnt/juno/SOFTWARE + +Then umount the USB device, and reboot, as above. + +Device trees +------------ +The device tree files for the boards are maintained in the Linux kernel +repository. They end up in the ``SOFTWARE/`` directory of the SD card, as +``juno.dtb``, ``juno-r1.dtb``, and ``juno-r2.dtb``, respectively. The MCC +firmware will look into the images.txt file matching the board revision, from +the ``SITE1/`` directory. Each version there will reference its respective DTB +file in ``SOFTWARE/``, and so the correct version will end in the NOR flash, in +the ``board.dtb`` partition. U-Boot picks its control DTB from there, you can +pass this on to a kernel using ``$fdtcontroladdr``. + +You can update the DTBs anytime, by building them using the ``dtbs`` make +target from a Linux kernel tree, then just copying the generated binaries +to the ``SOFTWARE/`` directory of the SD card. + +.. _`Juno development board`: https://developer.arm.com/tools-and-software/development-boards/juno-development-board +.. _`V2M-Juno TRM`: https://developer.arm.com/documentation/100113/latest +.. _`fiptool`: https://github.com/ARM-software/arm-trusted-firmware/tree/master/tools/fiptool +.. _`SCP firmware`: https://github.com/ARM-software/SCP-firmware.git From bba1cc9b8c857855f4db42dc9f92b0f98d78df25 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 11 Jan 2022 01:37:01 +0100 Subject: [PATCH 02/28] doc: Building on Alpine Linux Describe the required packages for building U-Boot on Alpine Linux Signed-off-by: Heinrich Schuchardt --- doc/build/gcc.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index cdd7970032..0e0d87a022 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -51,6 +51,16 @@ Depending on the build targets further packages maybe needed. zypper install bc bison flex gcc libopenssl-devel libSDL2-devel make \ ncurses-devel python3-devel python3-pytest swig +Alpine Linux +~~~~~~~~~~~~ + +For building U-Boot on Alpine Linux at least the following packages are needed: + +.. code-block:: bash + + apk add alpine-sdk bc bison dtc flex linux-headers ncurses-dev \ + openssl-dev python3 py3-setuptools python3-dev sdl2 + Prerequisites ------------- From 8804b276a7ebab31573ecbbf08832a54bdfad48d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 12 Jan 2022 02:35:00 +0100 Subject: [PATCH 03/28] .readthedocs.yml: update the requirements Fix an error: This project needs at least Sphinx v2.4.4. Signed-off-by: Heinrich Schuchardt --- .readthedocs.yml | 15 ++++++++++----- doc/sphinx/requirements.txt | 6 +++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 44949ea239..7c6c25541a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,6 +5,13 @@ # Required version: 2 +build: + os: "ubuntu-20.04" + apt_packages: + - python3-six + tools: + python: "3.9" + # Build documentation in the docs/ directory with Sphinx sphinx: configuration: doc/conf.py @@ -12,8 +19,6 @@ sphinx: # Optionally build your docs in additional formats such as PDF and ePub formats: [] -# Optionally set the version of Python and requirements required to build your docs -# python: -# version: 3.7 -# install: -# - requirements: docs/requirements.txt +python: + install: + - requirements: doc/sphinx/requirements.txt diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt index 4555a94d30..44c187880d 100644 --- a/doc/sphinx/requirements.txt +++ b/doc/sphinx/requirements.txt @@ -1,4 +1,4 @@ docutils==0.16 -Sphinx==3.4.3 -sphinx_rtd_theme -six +sphinx==3.4.3 +sphinx_rtd_theme==1.0.0 +six==1.16.0 From 797b2a2ed4a0d34ea521e6ee07a31bdb5bd8c14a Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:42 +0100 Subject: [PATCH 04/28] doc: add include/dm/uclass.h to the HTML documentation Correct Sphinx style comments in include/dm/uclass.h and add the driver model UCLASS API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 9 +++++ doc/api/index.rst | 1 + include/dm/uclass.h | 83 +++++++++++++++++++++++---------------------- 3 files changed, 52 insertions(+), 41 deletions(-) create mode 100644 doc/api/dm.rst diff --git a/doc/api/dm.rst b/doc/api/dm.rst new file mode 100644 index 0000000000..edce25da51 --- /dev/null +++ b/doc/api/dm.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Driver Model +============ + +Uclass and Driver +----------------- + +.. kernel-doc:: include/dm/uclass.h diff --git a/doc/api/index.rst b/doc/api/index.rst index 806c7385a6..3f36174167 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -7,6 +7,7 @@ U-Boot API documentation :maxdepth: 2 dfu + dm efi getopt linker_lists diff --git a/include/dm/uclass.h b/include/dm/uclass.h index f1fd2ba246..7f33c34214 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -84,7 +84,7 @@ struct udevice; * its children. If non-zero this is the size of this data, to be allocated * in the child device's parent_plat pointer. This value is only used as * a fallback if this member is 0 in the driver. - * @flags: Flags for this uclass (DM_UC_...) + * @flags: Flags for this uclass ``(DM_UC_...)`` */ struct uclass_driver { const char *name; @@ -127,17 +127,16 @@ struct uclass_driver { * build time. Before this is used, an extern UCLASS_DRIVER() must have been * declared. * - * For example: + * For example:: * - * extern UCLASS_DRIVER(clk); - * - * struct uclass_driver *drvs[] = { - * DM_UCLASS_DRIVER_REF(clk), - * }; + * extern UCLASS_DRIVER(clk); + * struct uclass_driver *drvs[] = { + * DM_UCLASS_DRIVER_REF(clk), + * }; * * @_name: Name of the uclass_driver. This must be a valid C identifier, used by * the linker_list. - * @returns struct uclass_driver * for the uclass driver + * Return: struct uclass_driver * for the uclass driver */ #define DM_UCLASS_DRIVER_REF(_name) \ ll_entry_ref(struct uclass_driver, _name, uclass_driver) @@ -145,8 +144,8 @@ struct uclass_driver { /** * uclass_get_priv() - Get the private data for a uclass * - * @uc Uclass to check - * @return private data, or NULL if none + * @uc: Uclass to check + * Return: private data, or NULL if none */ void *uclass_get_priv(const struct uclass *uc); @@ -159,8 +158,9 @@ void *uclass_get_priv(const struct uclass *uc); * * @key: ID to look up * @ucp: Returns pointer to uclass (there is only one per ID) - * @return 0 if OK, -EDEADLK if driver model is not yet inited, other -ve on - * other error + * Return: + * 0 if OK, -EDEADLK if driver model is not yet inited, + * other -ve on other error */ int uclass_get(enum uclass_id key, struct uclass **ucp); @@ -168,16 +168,16 @@ int uclass_get(enum uclass_id key, struct uclass **ucp); * uclass_get_name() - Get the name of a uclass driver * * @id: ID to look up - * @returns the name of the uclass driver for that ID, or NULL if none + * Return: the name of the uclass driver for that ID, or NULL if none */ const char *uclass_get_name(enum uclass_id id); /** - * uclass_get_by_name() - Look up a uclass by its driver name + * uclass_get_by_name_len() - Look up a uclass by its partial driver name * * @name: Name to look up - * @len: Length of name - * @returns the associated uclass ID, or UCLASS_INVALID if not found + * @len: Length of the partial name + * Return: the associated uclass ID, or UCLASS_INVALID if not found */ enum uclass_id uclass_get_by_name_len(const char *name, int len); @@ -185,7 +185,7 @@ enum uclass_id uclass_get_by_name_len(const char *name, int len); * uclass_get_by_name() - Look up a uclass by its driver name * * @name: Name to look up - * @returns the associated uclass ID, or UCLASS_INVALID if not found + * Return: the associated uclass ID, or UCLASS_INVALID if not found */ enum uclass_id uclass_get_by_name(const char *name); @@ -197,7 +197,7 @@ enum uclass_id uclass_get_by_name(const char *name); * @id: ID to look up * @index: Device number within that uclass (0=first) * @devp: Returns pointer to device (there is only one per for each ID) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp); @@ -211,7 +211,7 @@ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp); * @id: ID to look up * @name: name of a device to get * @devp: Returns pointer to device (the first one with the name) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device_by_name(enum uclass_id id, const char *name, struct udevice **devp); @@ -228,7 +228,7 @@ int uclass_get_device_by_name(enum uclass_id id, const char *name, * @id: ID to look up * @seq: Sequence number to find (0=first) * @devp: Returns pointer to device (there is only one for each seq) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp); @@ -243,7 +243,7 @@ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp); * @id: ID to look up * @node: Device tree offset to search for (if -ve then -ENODEV is returned) * @devp: Returns pointer to device (there is only one for each node) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device_by_of_offset(enum uclass_id id, int node, struct udevice **devp); @@ -257,9 +257,9 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node, * The device is probed to activate it ready for use. * * @id: ID to look up - * @np: Device tree node to search for (if NULL then -ENODEV is returned) + * @node: Device tree node to search for (if NULL then -ENODEV is returned) * @devp: Returns pointer to device (there is only one for each node) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node, struct udevice **devp); @@ -271,12 +271,13 @@ int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node, * * The device is probed to activate it ready for use. * - * @id: uclass ID to look up + * @id: uclass ID to look up * @phandle_id: the phandle id to look up - * @devp: Returns pointer to device (there is only one for each node). NULL if - * there is no such device. - * @return 0 if OK, -ENODEV if there is no device match the phandle, other - * -ve on error + * @devp: Returns pointer to device (there is only one for each node). + * NULL if there is no such device. + * Return: + * 0 if OK, -ENODEV if there is no device match the phandle, + * other -ve on error */ int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id, struct udevice **devp); @@ -292,8 +293,8 @@ int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id, * @parent: Parent device containing the phandle pointer * @name: Name of property in the parent device node * @devp: Returns pointer to device (there is only one for each node) - * @return 0 if OK, -ENOENT if there is no @name present in the node, other - * -ve on error + * Return: 0 if OK, -ENOENT if there is no @name present in the node, other + * -ve on error */ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, const char *name, struct udevice **devp); @@ -310,7 +311,7 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, * @id: ID to look up * @drv: Driver to look for * @devp: Returns pointer to the first device with that driver - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, struct udevice **devp); @@ -327,7 +328,7 @@ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, * @devp: Returns pointer to the first device in that uclass if no error * occurred, or NULL if there is no first device, or an error occurred with * that device. - * @return 0 if OK (found or not found), other -ve on error + * Return: 0 if OK (found or not found), other -ve on error */ int uclass_first_device(enum uclass_id id, struct udevice **devp); @@ -338,7 +339,7 @@ int uclass_first_device(enum uclass_id id, struct udevice **devp); * * @id: Uclass ID to look up * @devp: Returns pointer to the first device in that uclass, or NULL if none - * @return 0 if found, -ENODEV if not found, other -ve on error + * Return: 0 if found, -ENODEV if not found, other -ve on error */ int uclass_first_device_err(enum uclass_id id, struct udevice **devp); @@ -353,7 +354,7 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp); * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the uclass if no error occurred, or NULL if there is * no next device, or an error occurred with that next device. - * @return 0 if OK (found or not found), other -ve on error + * Return: 0 if OK (found or not found), other -ve on error */ int uclass_next_device(struct udevice **devp); @@ -365,7 +366,7 @@ int uclass_next_device(struct udevice **devp); * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the uclass if no error occurred, or NULL if * there is no next device. - * @return 0 if found, -ENODEV if not found, other -ve on error + * Return: 0 if found, -ENODEV if not found, other -ve on error */ int uclass_next_device_err(struct udevice **devp); @@ -380,7 +381,7 @@ int uclass_next_device_err(struct udevice **devp); * @id: Uclass ID to look up * @devp: Returns pointer to the first device in that uclass, or NULL if there * is no first device - * @return 0 if OK (found or not found), other -ve on error. If an error occurs + * Return: 0 if OK (found or not found), other -ve on error. If an error occurs * it is still possible to move to the next device. */ int uclass_first_device_check(enum uclass_id id, struct udevice **devp); @@ -395,7 +396,7 @@ int uclass_first_device_check(enum uclass_id id, struct udevice **devp); * * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the uclass if any - * @return 0 if OK (found or not found), other -ve on error. If an error occurs + * Return: 0 if OK (found or not found), other -ve on error. If an error occurs * it is still possible to move to the next device. */ int uclass_next_device_check(struct udevice **devp); @@ -409,7 +410,7 @@ int uclass_next_device_check(struct udevice **devp); * @id: Uclass ID to check * @driver_data: Driver data to search for * @devp: Returns pointer to the first matching device in that uclass, if found - * @return 0 if found, -ENODEV if not found, other -ve on error + * Return: 0 if found, -ENODEV if not found, other -ve on error */ int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, struct udevice **devp); @@ -421,7 +422,7 @@ int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, * looking for its ID. * * @id: uclass ID to look up - * @return 0 if OK, other -ve on error + * Return: 0 if OK, other -ve on error */ int uclass_probe_all(enum uclass_id id); @@ -429,7 +430,7 @@ int uclass_probe_all(enum uclass_id id); * uclass_id_count() - Count the number of devices in a uclass * * @id: uclass ID to look up - * @return number of devices in that uclass (0 if none) + * Return: number of devices in that uclass (0 if none) */ int uclass_id_count(enum uclass_id id); @@ -444,7 +445,7 @@ int uclass_id_count(enum uclass_id id); * @id: enum uclass_id ID to use * @pos: struct udevice * to hold the current device. Set to NULL when there * are no more devices. - * @uc: temporary uclass variable (struct uclass *) + * @uc: temporary uclass variable (``struct uclass *``) */ #define uclass_id_foreach_dev(id, pos, uc) \ if (!uclass_get(id, &uc)) \ From 0cdd7ded8887d41d83f518e7b352972e58b47a1e Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:43 +0100 Subject: [PATCH 05/28] doc: add include/dm/root.h to the HTML documentation Correct Sphinx style comments in include/dm/devres.h and add the associated driver model API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/root.h | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index edce25da51..181a454c24 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -7,3 +7,4 @@ Uclass and Driver ----------------- .. kernel-doc:: include/dm/uclass.h +.. kernel-doc:: include/dm/root.h diff --git a/include/dm/root.h b/include/dm/root.h index 780f269db6..e888fb993c 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -19,7 +19,7 @@ extern struct list_head uclass_head; * * This function returns pointer to the root node of the driver tree, * - * @return pointer to root device, or NULL if not inited yet + * Return: pointer to root device, or NULL if not inited yet */ struct udevice *dm_root(void); @@ -27,6 +27,8 @@ struct global_data; /** * dm_fixup_for_gd_move() - Handle global_data moving to a new place * + * @new_gd: Pointer to the new global data + * * The uclass list is part of global_data. Due to the way lists work, moving * the list will cause it to become invalid. This function fixes that up so * that the uclass list will work correctly. @@ -40,7 +42,7 @@ void dm_fixup_for_gd_move(struct global_data *new_gd); * * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC * flag. If false bind all drivers. - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_scan_plat(bool pre_reloc_only); @@ -52,7 +54,7 @@ int dm_scan_plat(bool pre_reloc_only); * * @pre_reloc_only: If true, bind only nodes with special devicetree properties, * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_scan_fdt(bool pre_reloc_only); @@ -65,7 +67,7 @@ int dm_scan_fdt(bool pre_reloc_only); * * @pre_reloc_only: If true, bind only nodes with special devicetree properties, * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_extended_scan(bool pre_reloc_only); @@ -79,7 +81,7 @@ int dm_extended_scan(bool pre_reloc_only); * * @pre_reloc_only: If true, bind only nodes with special devicetree properties, * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_scan_other(bool pre_reloc_only); @@ -92,7 +94,7 @@ int dm_scan_other(bool pre_reloc_only); * * @pre_reloc_only: If true, bind only nodes with special devicetree properties, * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_init_and_scan(bool pre_reloc_only); @@ -103,7 +105,7 @@ int dm_init_and_scan(bool pre_reloc_only); * This needs to be called before anything uses the DM * * @of_live: Enable live device tree - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_init(bool of_live); @@ -111,7 +113,7 @@ int dm_init(bool of_live); * dm_uninit - Uninitialise Driver Model structures * * All devices will be removed and unbound - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_uninit(void); @@ -124,7 +126,7 @@ int dm_uninit(void); * All devices with the matching flags set will be removed * * @flags: Flags for selective device removal - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_remove_devices_flags(uint flags); #else From cbb14ac92c1a40201aae0328b3af690dff133ecd Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:44 +0100 Subject: [PATCH 06/28] doc: add include/dm/lists.h to the HTML documentation Correct Sphinx style comments in include/dm/lists.h and add the list API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/lists.h | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 181a454c24..168d129250 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -8,3 +8,4 @@ Uclass and Driver .. kernel-doc:: include/dm/uclass.h .. kernel-doc:: include/dm/root.h +.. kernel-doc:: include/dm/lists.h diff --git a/include/dm/lists.h b/include/dm/lists.h index 5896ae3658..fc3b4ae585 100644 --- a/include/dm/lists.h +++ b/include/dm/lists.h @@ -19,13 +19,14 @@ * for binding a driver given its name and plat. * * @name: Name of driver to look up - * @return pointer to driver, or NULL if not found + * Return: pointer to driver, or NULL if not found */ struct driver *lists_driver_lookup_name(const char *name); /** * lists_uclass_lookup() - Return uclass_driver based on ID of the class - * id: ID of the class + * + * @id: ID of the class * * This function returns the pointer to uclass_driver, which is the class's * base structure based on the ID of the class. Returns NULL on error. @@ -56,7 +57,8 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only); * @drv: if non-NULL, force this driver to be bound * @pre_reloc_only: If true, bind only nodes with special devicetree properties, * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. - * @return 0 if device was bound, -EINVAL if the device tree is invalid, + * + * Return: 0 if device was bound, -EINVAL if the device tree is invalid, * other -ve value on error */ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, From ca4ca43e2f245a03b0953e723e38c49c676af78c Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:45 +0100 Subject: [PATCH 07/28] doc: add include/dm/platdata.h to the HTML documentation Correct Sphinx style comments in include/dm/platdata.h and add the associated API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/platdata.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 168d129250..6f72b0b620 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -9,3 +9,4 @@ Uclass and Driver .. kernel-doc:: include/dm/uclass.h .. kernel-doc:: include/dm/root.h .. kernel-doc:: include/dm/lists.h +.. kernel-doc:: include/dm/platdata.h diff --git a/include/dm/platdata.h b/include/dm/platdata.h index 4efb1dfe12..47ba8aab7a 100644 --- a/include/dm/platdata.h +++ b/include/dm/platdata.h @@ -40,7 +40,7 @@ struct driver_info { #endif /** - * driver_rt - runtime information set up by U-Boot + * struct driver_rt - runtime information set up by U-Boot * * There is one of these for every driver_info in the linker list, indexed by * the driver_info idx value. @@ -51,7 +51,7 @@ struct driver_rt { struct udevice *dev; }; -/** +/* * NOTE: Avoid using these except in extreme circumstances, where device tree * is not feasible (e.g. serial driver in SPL where <8KB of SRAM is * available). U-Boot's driver model uses device tree for configuration. From 9fb1c77ef645232b95aa15e6f445aba8559186e1 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:46 +0100 Subject: [PATCH 08/28] doc: add include/dm/device.h to the HTML documentation Correct Sphinx style comments in include/dm/device.h and add the driver model device API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 5 ++ include/dm/device.h | 209 ++++++++++++++++++++++++-------------------- 2 files changed, 121 insertions(+), 93 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 6f72b0b620..7a77a91c1f 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -10,3 +10,8 @@ Uclass and Driver .. kernel-doc:: include/dm/root.h .. kernel-doc:: include/dm/lists.h .. kernel-doc:: include/dm/platdata.h + +Device +------ + +.. kernel-doc:: include/dm/device.h diff --git a/include/dm/device.h b/include/dm/device.h index cf785f7ae2..435a1114f1 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -145,7 +145,7 @@ enum { * @uclass_node: Used by uclass to link its devices * @child_head: List of children of this device * @sibling_node: Next device in list of all devices - * @flags_: Flags for this device DM_FLAG_... (do not access outside driver + * @flags_: Flags for this device `DM_FLAG_...` (do not access outside driver * model) * @seq_: Allocated sequence number for this device (-1 = none). This is set up * when the device is bound and is unique within the device's uclass. If the @@ -193,14 +193,14 @@ struct udevice { }; /** - * udevice_rt - runtime information set up by U-Boot + * struct udevice_rt - runtime information set up by U-Boot * * This is only used with OF_PLATDATA_RT * * There is one of these for every udevice in the linker list, indexed by * the udevice_info idx value. * - * @flags_: Flags for this device DM_FLAG_... (do not access outside driver + * @flags_: Flags for this device `DM_FLAG_...` (do not access outside driver * model) */ struct udevice_rt { @@ -239,7 +239,7 @@ static inline void dev_bic_flags(struct udevice *dev, u32 bic) * dev_ofnode() - get the DT node reference associated with a udevice * * @dev: device to check - * @return reference of the the device's DT node + * Return: reference of the device's DT node */ static inline ofnode dev_ofnode(const struct udevice *dev) { @@ -351,7 +351,7 @@ struct udevice_id { * @ops: Driver-specific operations. This is typically a list of function * pointers defined by the driver, to implement driver functions required by * the uclass. - * @flags: driver flags - see DM_FLAGS_... + * @flags: driver flags - see `DM_FLAGS_...` * @acpi_ops: Advanced Configuration and Power Interface (ACPI) operations, * allowing the device to add things to the ACPI tables passed to Linux */ @@ -378,11 +378,24 @@ struct driver { #endif }; -/* Declare a new U-Boot driver */ +/** + * U_BOOT_DRIVER() - Declare a new U-Boot driver + * @__name: name of the driver + */ #define U_BOOT_DRIVER(__name) \ ll_entry_declare(struct driver, __name, driver) -/* Get a pointer to a given driver */ +/** + * DM_DRIVER_GET() - Get a pointer to a given driver + * + * This is useful in code for referencing a driver at build time. + * Before this is used, an extern U_BOOT_DRIVER() must have been + * declared. + * + * @__name: Name of the driver. This must be a valid C identifier, + * used by the linker_list + * Return: struct driver * for the driver + */ #define DM_DRIVER_GET(__name) \ ll_entry_get(struct driver, __name, driver) @@ -392,60 +405,69 @@ struct driver { * This is useful in data structures and code for referencing a driver at * build time. Before this is used, an extern U_BOOT_DRIVER() must have been * declared. + * This is like DM_DRIVER_GET, but without the extra code, so it is suitable + * for putting into data structures. * - * For example: + * For example:: * - * extern U_BOOT_DRIVER(sandbox_fixed_clock); + * extern U_BOOT_DRIVER(sandbox_fixed_clock); + * struct driver *drvs[] = { + * DM_DRIVER_REF(sandbox_fixed_clock), + * }; * - * struct driver *drvs[] = { - * DM_DRIVER_REF(sandbox_fixed_clock), - * }; - * - * @_name: Name of the driver. This must be a valid C identifier, used by the - * linker_list - * @returns struct driver * for the driver + * @_name: Name of the driver. This must be a valid C identifier, + * used by the linker_list + * Return: struct driver * for the driver */ #define DM_DRIVER_REF(_name) \ ll_entry_ref(struct driver, _name, driver) /** - * Declare a macro to state a alias for a driver name. This macro will - * produce no code but its information will be parsed by tools like - * dtoc + * DM_DRIVER_ALIAS() - Declare a macro to state an alias for a driver name + * + * This macro will produce no code but its information will be parsed by tools + * like dtoc + * + * @__name: name of driver + * @__alias: alias for the driver name */ #define DM_DRIVER_ALIAS(__name, __alias) /** - * Declare a macro to indicate which phase of U-Boot this driver is fore. - * + * DM_PHASE() - Declare a macro to indicate which phase of U-Boot this driver is for. * * This macro produces no code but its information will be parsed by dtoc. The * macro can be only be used once in a driver. Put it within the U_BOOT_DRIVER() - * declaration, e.g.: + * declaration, e.g.:: * - * U_BOOT_DRIVER(cpu) = { - * .name = ... - * ... - * DM_PHASE(tpl) - * }; + * U_BOOT_DRIVER(cpu) = { + * .name = ... + * ... + * DM_PHASE(tpl) + * }; + * + * @_phase: Associated phase of U-Boot ("spl", "tpl") */ #define DM_PHASE(_phase) /** - * Declare a macro to declare a header needed for a driver. Often the correct - * header can be found automatically, but only for struct declarations. For - * enums and #defines used in the driver declaration and declared in a different - * header from the structs, this macro must be used. + * DM_HEADER() - Declare a macro to declare a header needed for a driver. + * + * Often the correct header can be found automatically, but only for struct + * declarations. For enums and #defines used in the driver declaration and + * declared in a different header from the structs, this macro must be used. * * This macro produces no code but its information will be parsed by dtoc. The * macro can be used multiple times with different headers, for the same driver. - * Put it within the U_BOOT_DRIVER() declaration, e.g.: + * Put it within the U_BOOT_DRIVER() declaration, e.g.:: * - * U_BOOT_DRIVER(cpu) = { - * .name = ... - * ... - * DM_HEADER() - * }; + * U_BOOT_DRIVER(cpu) = { + * .name = ... + * ... + * DM_HEADER() + * }; + * + * @_hdr: header needed for a driver */ #define DM_HEADER(_hdr) @@ -454,8 +476,8 @@ struct driver { * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return platform data, or NULL if none + * @dev: Device to check + * Return: platform data, or NULL if none */ void *dev_get_plat(const struct udevice *dev); @@ -464,8 +486,8 @@ void *dev_get_plat(const struct udevice *dev); * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return parent's platform data, or NULL if none + * @dev: Device to check + * Return: parent's platform data, or NULL if none */ void *dev_get_parent_plat(const struct udevice *dev); @@ -474,8 +496,8 @@ void *dev_get_parent_plat(const struct udevice *dev); * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return uclass's platform data, or NULL if none + * @dev: Device to check + * Return: uclass's platform data, or NULL if none */ void *dev_get_uclass_plat(const struct udevice *dev); @@ -484,8 +506,8 @@ void *dev_get_uclass_plat(const struct udevice *dev); * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return private data, or NULL if none + * @dev: Device to check + * Return: private data, or NULL if none */ void *dev_get_priv(const struct udevice *dev); @@ -498,8 +520,8 @@ void *dev_get_priv(const struct udevice *dev); * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return parent data, or NULL if none + * @dev: Device to check + * Return: parent data, or NULL if none */ void *dev_get_parent_priv(const struct udevice *dev); @@ -508,16 +530,16 @@ void *dev_get_parent_priv(const struct udevice *dev); * * This checks that dev is not NULL, but no other checks for now * - * @dev Device to check - * @return private uclass data for this device, or NULL if none + * @dev: Device to check + * Return: private uclass data for this device, or NULL if none */ void *dev_get_uclass_priv(const struct udevice *dev); /** - * struct dev_get_parent() - Get the parent of a device + * dev_get_parent() - Get the parent of a device * * @child: Child to check - * @return parent of child, or NULL if this is the root device + * Return: parent of child, or NULL if this is the root device */ struct udevice *dev_get_parent(const struct udevice *child); @@ -529,13 +551,14 @@ struct udevice *dev_get_parent(const struct udevice *child); * returns the associated data value for that compatible string. This is * the 'data' field in struct udevice_id. * - * As an example, consider this structure: - * static const struct udevice_id tegra_i2c_ids[] = { - * { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, - * { .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD }, - * { .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC }, - * { } - * }; + * As an example, consider this structure:: + * + * static const struct udevice_id tegra_i2c_ids[] = { + * { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, + * { .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD }, + * { .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC }, + * { } + * }; * * When driver model finds a driver for this it will store the 'data' value * corresponding to the compatible string it matches. This function returns @@ -544,7 +567,7 @@ struct udevice *dev_get_parent(const struct udevice *child); * For USB devices, this is the driver_info field in struct usb_device_id. * * @dev: Device to check - * @return driver data (0 if none is provided) + * Return: driver data (0 if none is provided) */ ulong dev_get_driver_data(const struct udevice *dev); @@ -555,7 +578,7 @@ ulong dev_get_driver_data(const struct udevice *dev); * driver's operations. * * @dev: Device to check - * @return void pointer to driver's operations or NULL for NULL-dev or NULL-ops + * Return: void pointer to driver's operations or NULL for NULL-dev or NULL-ops */ const void *dev_get_driver_ops(const struct udevice *dev); @@ -563,7 +586,7 @@ const void *dev_get_driver_ops(const struct udevice *dev); * device_get_uclass_id() - return the uclass ID of a device * * @dev: Device to check - * @return uclass ID for the device + * Return: uclass ID for the device */ enum uclass_id device_get_uclass_id(const struct udevice *dev); @@ -573,7 +596,7 @@ enum uclass_id device_get_uclass_id(const struct udevice *dev); * This checks that dev is not NULL. * * @dev: Device to check - * @return pointer to the uclass name for the device + * Return: pointer to the uclass name for the device */ const char *dev_get_uclass_name(const struct udevice *dev); @@ -583,11 +606,11 @@ const char *dev_get_uclass_name(const struct udevice *dev); * Returns the numbered child, 0 being the first. This does not use * sequence numbers, only the natural order. * - * @dev: Parent device to check + * @parent: Parent device to check * @index: Child index * @devp: Returns pointer to device - * @return 0 if OK, -ENODEV if no such device, other error if the device fails - * to probe + * Return: + * 0 if OK, -ENODEV if no such device, other error if the device fails to probe */ int device_get_child(const struct udevice *parent, int index, struct udevice **devp); @@ -619,7 +642,7 @@ int device_get_decendent_count(const struct udevice *parent); * @seq: Sequence number to find (0=first) * @devp: Returns pointer to device (there is only one per for each seq). * Set to NULL if none is found - * @return 0 if OK, -ENODEV if not found + * Return: 0 if OK, -ENODEV if not found */ int device_find_child_by_seq(const struct udevice *parent, int seq, struct udevice **devp); @@ -637,7 +660,7 @@ int device_find_child_by_seq(const struct udevice *parent, int seq, * @seq: Sequence number to find (0=first) * @devp: Returns pointer to device (there is only one per for each seq) * Set to NULL if none is found - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_get_child_by_seq(const struct udevice *parent, int seq, struct udevice **devp); @@ -650,7 +673,7 @@ int device_get_child_by_seq(const struct udevice *parent, int seq, * @parent: Parent device * @of_offset: Device tree offset to find * @devp: Returns pointer to device if found, otherwise this is set to NULL - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_find_child_by_of_offset(const struct udevice *parent, int of_offset, struct udevice **devp); @@ -665,7 +688,7 @@ int device_find_child_by_of_offset(const struct udevice *parent, int of_offset, * @parent: Parent device * @of_offset: Device tree offset to find * @devp: Returns pointer to device if found, otherwise this is set to NULL - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_get_child_by_of_offset(const struct udevice *parent, int of_offset, struct udevice **devp); @@ -680,7 +703,7 @@ int device_get_child_by_of_offset(const struct udevice *parent, int of_offset, * * @node: Device tree ofnode to find * @devp: Returns pointer to device if found, otherwise this is set to NULL - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_find_global_by_ofnode(ofnode node, struct udevice **devp); @@ -695,7 +718,7 @@ int device_find_global_by_ofnode(ofnode node, struct udevice **devp); * * @node: Device tree ofnode to find * @devp: Returns pointer to device if found, otherwise this is set to NULL - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_get_global_by_ofnode(ofnode node, struct udevice **devp); @@ -715,7 +738,7 @@ int device_get_global_by_ofnode(ofnode node, struct udevice **devp); * * @idx: Index number of the driver_info/udevice structure (0=first) * @devp: Returns pointer to device if found, otherwise this is set to NULL - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int device_get_by_ofplat_idx(uint idx, struct udevice **devp); @@ -724,7 +747,7 @@ int device_get_by_ofplat_idx(uint idx, struct udevice **devp); * * @parent: Parent device to search * @devp: Returns first child device, or NULL if none - * @return 0 + * Return: 0 */ int device_find_first_child(const struct udevice *parent, struct udevice **devp); @@ -734,7 +757,7 @@ int device_find_first_child(const struct udevice *parent, * * @devp: Pointer to previous child device on entry. Returns pointer to next * child device, or NULL if none - * @return 0 + * Return: 0 */ int device_find_next_child(struct udevice **devp); @@ -749,7 +772,7 @@ int device_find_next_child(struct udevice **devp); * @parent: Parent device to search * @uclass_id: Uclass to look for * @devp: Returns device found, if any, else NULL - * @return 0 if found, else -ENODEV + * Return: 0 if found, else -ENODEV */ int device_find_first_inactive_child(const struct udevice *parent, enum uclass_id uclass_id, @@ -761,7 +784,7 @@ int device_find_first_inactive_child(const struct udevice *parent, * @parent: Parent device to search * @uclass_id: Uclass to look for * @devp: Returns first child device in that uclass, if any, else NULL - * @return 0 if found, else -ENODEV + * Return: 0 if found, else -ENODEV */ int device_find_first_child_by_uclass(const struct udevice *parent, enum uclass_id uclass_id, @@ -774,7 +797,7 @@ int device_find_first_child_by_uclass(const struct udevice *parent, * @name: Name to look for * @len: Length of the name * @devp: Returns device found, if any - * @return 0 if found, else -ENODEV + * Return: 0 if found, else -ENODEV */ int device_find_child_by_namelen(const struct udevice *parent, const char *name, int len, struct udevice **devp); @@ -785,7 +808,7 @@ int device_find_child_by_namelen(const struct udevice *parent, const char *name, * @parent: Parent device to search * @name: Name to look for * @devp: Returns device found, if any - * @return 0 if found, else -ENODEV + * Return: 0 if found, else -ENODEV */ int device_find_child_by_name(const struct udevice *parent, const char *name, struct udevice **devp); @@ -798,7 +821,7 @@ int device_find_child_by_name(const struct udevice *parent, const char *name, * * @parent: Parent to check * @devp: Returns child that was found, if any - * @return 0 on success, -ENODEV if no children, other -ve on error + * Return: 0 on success, -ENODEV if no children, other -ve on error */ int device_first_child_ofdata_err(struct udevice *parent, struct udevice **devp); @@ -811,7 +834,7 @@ int device_first_child_ofdata_err(struct udevice *parent, * * @devp: On entry, points to the previous child; on exit returns the child that * was found, if any - * @return 0 on success, -ENODEV if no children, other -ve on error + * Return: 0 on success, -ENODEV if no children, other -ve on error */ int device_next_child_ofdata_err(struct udevice **devp); @@ -822,7 +845,7 @@ int device_next_child_ofdata_err(struct udevice **devp); * * @parent: Parent device to search * @devp: Returns device found, if any - * @return 0 if found, -ENODEV if not, -ve error if device failed to probe + * Return: 0 if found, -ENODEV if not, -ve error if device failed to probe */ int device_first_child_err(struct udevice *parent, struct udevice **devp); @@ -833,7 +856,7 @@ int device_first_child_err(struct udevice *parent, struct udevice **devp); * * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next sibling if no error occurred - * @return 0 if found, -ENODEV if not, -ve error if device failed to probe + * Return: 0 if found, -ENODEV if not, -ve error if device failed to probe */ int device_next_child_err(struct udevice **devp); @@ -841,7 +864,7 @@ int device_next_child_err(struct udevice **devp); * device_has_children() - check if a device has any children * * @dev: Device to check - * @return true if the device has one or more children + * Return: true if the device has one or more children */ bool device_has_children(const struct udevice *dev); @@ -849,7 +872,7 @@ bool device_has_children(const struct udevice *dev); * device_has_active_children() - check if a device has any active children * * @dev: Device to check - * @return true if the device has one or more children and at least one of + * Return: true if the device has one or more children and at least one of * them is active (probed). */ bool device_has_active_children(const struct udevice *dev); @@ -862,7 +885,7 @@ bool device_has_active_children(const struct udevice *dev); * view of devices is being displayed. * * @dev: Device to check - * @return true if there are no more siblings after this one - i.e. is it + * Return: true if there are no more siblings after this one - i.e. is it * last in the list. */ bool device_is_last_sibling(const struct udevice *dev); @@ -880,7 +903,7 @@ bool device_is_last_sibling(const struct udevice *dev); * @dev: Device to update * @name: New name (this string is allocated new memory and attached to * the device) - * @return 0 if OK, -ENOMEM if there is not enough memory to allocate the + * Return: 0 if OK, -ENOMEM if there is not enough memory to allocate the * string */ int device_set_name(struct udevice *dev, const char *name); @@ -903,7 +926,7 @@ void device_set_name_alloced(struct udevice *dev); * @dev: udevice pointer for which compatible needs to be verified. * @compat: Compatible string which needs to verified in the given * device - * @return true if OK, false if the compatible is not found + * Return: true if OK, false if the compatible is not found */ bool device_is_compatible(const struct udevice *dev, const char *compat); @@ -914,7 +937,7 @@ bool device_is_compatible(const struct udevice *dev, const char *compat); * This allows to check whether the machine is comaptible with the compat. * * @compat: Compatible string which needs to verified - * @return true if OK, false if the compatible is not found + * Return: true if OK, false if the compatible is not found */ bool of_machine_is_compatible(const char *compat); @@ -922,7 +945,7 @@ bool of_machine_is_compatible(const char *compat); * dev_disable_by_path() - Disable a device given its device tree path * * @path: The device tree path identifying the device to be disabled - * @return 0 on success, -ve on error + * Return: 0 on success, -ve on error */ int dev_disable_by_path(const char *path); @@ -930,7 +953,7 @@ int dev_disable_by_path(const char *path); * dev_enable_by_path() - Enable a device given its device tree path * * @path: The device tree path identifying the device to be enabled - * @return 0 on success, -ve on error + * Return: 0 on success, -ve on error */ int dev_enable_by_path(const char *path); @@ -938,7 +961,7 @@ int dev_enable_by_path(const char *path); * device_is_on_pci_bus - Test if a device is on a PCI bus * * @dev: device to test - * @return: true if it is on a PCI bus, false otherwise + * Return: true if it is on a PCI bus, false otherwise */ static inline bool device_is_on_pci_bus(const struct udevice *dev) { @@ -971,7 +994,7 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev) * * This stops when it gets an error, with @pos set to the device that failed to * read ofdata. - + * * This creates a for() loop which works through the available children of * a device in order from start to end. Device ofdata is read by calling * device_of_to_plat() on each one. The devices are not probed. @@ -1012,7 +1035,7 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev) * be bound. * * @dev: Device to scan - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dm_scan_fdt_dev(struct udevice *dev); From 494bc8e6f0f125cf706f27aac1a219f3eb3c8565 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:47 +0100 Subject: [PATCH 09/28] doc: add include/dm/devres.h to the HTML documentation Correct Sphinx style comments in include/dm/devres.h and add the driver model device resource API, devres_*(), to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/devres.h | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 7a77a91c1f..0342620786 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -15,3 +15,4 @@ Device ------ .. kernel-doc:: include/dm/device.h +.. kernel-doc:: include/dm/devres.h diff --git a/include/dm/devres.h b/include/dm/devres.h index 17bb1ee8da..0ab277ec38 100644 --- a/include/dm/devres.h +++ b/include/dm/devres.h @@ -51,7 +51,7 @@ void *_devres_alloc(dr_release_t release, size_t size, gfp_t gfp); * with @release. The returned pointer can be passed to * other devres_*() functions. * - * RETURNS: + * Return: * Pointer to allocated devres on success, NULL on failure. */ #define devres_alloc(release, size, gfp) \ @@ -87,7 +87,7 @@ void devres_add(struct udevice *dev, void *res); * and for which @match returns 1. If @match is NULL, it's considered * to match all. * - * @return pointer to found devres, NULL if not found. + * Return: pointer to found devres, NULL if not found. */ void *devres_find(struct udevice *dev, dr_release_t release, dr_match_t match, void *match_data); @@ -103,7 +103,7 @@ void *devres_find(struct udevice *dev, dr_release_t release, * as @new_res and for which @match return 1. If found, @new_res is * freed; otherwise, @new_res is added atomically. * - * @return ointer to found or added devres. + * Return: pointer to found or added devres. */ void *devres_get(struct udevice *dev, void *new_res, dr_match_t match, void *match_data); @@ -120,7 +120,7 @@ void *devres_get(struct udevice *dev, void *new_res, * match all. If found, the resource is removed atomically and * returned. * - * @return ointer to removed devres on success, NULL if not found. + * Return: pointer to removed devres on success, NULL if not found. */ void *devres_remove(struct udevice *dev, dr_release_t release, dr_match_t match, void *match_data); @@ -140,7 +140,7 @@ void *devres_remove(struct udevice *dev, dr_release_t release, * only the devres-allocated data will be freed. The caller becomes * responsible for freeing any other data. * - * @return 0 if devres is found and freed, -ENOENT if not found. + * Return: 0 if devres is found and freed, -ENOENT if not found. */ int devres_destroy(struct udevice *dev, dr_release_t release, dr_match_t match, void *match_data); @@ -157,7 +157,7 @@ int devres_destroy(struct udevice *dev, dr_release_t release, * match all. If found, the resource is removed atomically, the * release function called and the resource freed. * - * @return 0 if devres is found and freed, -ENOENT if not found. + * Return: 0 if devres is found and freed, -ENOENT if not found. */ int devres_release(struct udevice *dev, dr_release_t release, dr_match_t match, void *match_data); @@ -173,7 +173,7 @@ int devres_release(struct udevice *dev, dr_release_t release, * automatically freed on driver detach. Like all other devres * resources, guaranteed alignment is unsigned long long. * - * @return pointer to allocated memory on success, NULL on failure. + * Return: pointer to allocated memory on success, NULL on failure. */ void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp); static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp) From 6de6a615f8527b722b512b0ea36821ab2439b773 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:48 +0100 Subject: [PATCH 10/28] doc: add include/dm/read.h to the HTML documentation Correct Sphinx style comments in include/dm/read.h and add the device read from device tree API to the HTML documentation. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/read.h | 161 +++++++++++++++++++++++----------------------- 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 0342620786..19a473f1f0 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -16,3 +16,4 @@ Device .. kernel-doc:: include/dm/device.h .. kernel-doc:: include/dm/devres.h +.. kernel-doc:: include/dm/read.h diff --git a/include/dm/read.h b/include/dm/read.h index 75c6ad6ee4..233af3c063 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -37,7 +37,7 @@ static inline const struct device_node *dev_np(const struct udevice *dev) * @dev: device to read DT property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp); @@ -47,7 +47,7 @@ int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp); * @dev: device to read DT property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ int dev_read_u32_default(const struct udevice *dev, const char *propname, int def); @@ -60,7 +60,7 @@ int dev_read_u32_default(const struct udevice *dev, const char *propname, * @propname: name of the property to read from * @index: index of the integer to return * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dev_read_u32_index(struct udevice *dev, const char *propname, int index, u32 *outp); @@ -73,7 +73,7 @@ int dev_read_u32_index(struct udevice *dev, const char *propname, int index, * @propname: name of the property to read from * @index: index of the integer to return * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ u32 dev_read_u32_index_default(struct udevice *dev, const char *propname, int index, u32 def); @@ -84,7 +84,7 @@ u32 dev_read_u32_index_default(struct udevice *dev, const char *propname, * @dev: device to read DT property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp); @@ -94,7 +94,7 @@ int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp); * @dev: device to read DT property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ int dev_read_s32_default(const struct udevice *dev, const char *propname, int def); @@ -107,7 +107,7 @@ int dev_read_s32_default(const struct udevice *dev, const char *propname, * @dev: device to read DT property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dev_read_u32u(const struct udevice *dev, const char *propname, uint *outp); @@ -117,7 +117,7 @@ int dev_read_u32u(const struct udevice *dev, const char *propname, uint *outp); * @dev: device to read DT property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int dev_read_u64(const struct udevice *dev, const char *propname, u64 *outp); @@ -127,7 +127,7 @@ int dev_read_u64(const struct udevice *dev, const char *propname, u64 *outp); * @dev: device to read DT property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ u64 dev_read_u64_default(const struct udevice *dev, const char *propname, u64 def); @@ -137,7 +137,7 @@ u64 dev_read_u64_default(const struct udevice *dev, const char *propname, * * @dev: device to read DT property from * @propname: name of the property to read - * @return string from property value, or NULL if there is no such property + * Return: string from property value, or NULL if there is no such property */ const char *dev_read_string(const struct udevice *dev, const char *propname); @@ -146,7 +146,7 @@ const char *dev_read_string(const struct udevice *dev, const char *propname); * * @dev: device to read DT property from * @propname: name of property to read - * @return true if property is present (meaning true), false if not present + * Return: true if property is present (meaning true), false if not present */ bool dev_read_bool(const struct udevice *dev, const char *propname); @@ -155,17 +155,17 @@ bool dev_read_bool(const struct udevice *dev, const char *propname); * * @dev: device whose DT node contains the subnode * @subnode_name: name of subnode to find - * @return reference to subnode (which can be invalid if there is no such + * Return: reference to subnode (which can be invalid if there is no such * subnode) */ -ofnode dev_read_subnode(const struct udevice *dev, const char *subbnode_name); +ofnode dev_read_subnode(const struct udevice *dev, const char *subnode_name); /** * dev_read_size() - read the size of a property * * @dev: device to check * @propname: property to check - * @return size of property if present, or -EINVAL if not + * Return: size of property if present, or -EINVAL if not */ int dev_read_size(const struct udevice *dev, const char *propname); @@ -176,7 +176,7 @@ int dev_read_size(const struct udevice *dev, const char *propname); * @index: the 'reg' property can hold a list of pairs * and @index is used to select which one is required * - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr_index(const struct udevice *dev, int index); @@ -188,7 +188,7 @@ fdt_addr_t dev_read_addr_index(const struct udevice *dev, int index); * @index: the 'reg' property can hold a list of pairs * and @index is used to select which one is required * - * @return pointer or NULL if not found + * Return: pointer or NULL if not found */ void *dev_read_addr_index_ptr(const struct udevice *dev, int index); @@ -200,7 +200,7 @@ void *dev_read_addr_index_ptr(const struct udevice *dev, int index); * and @index is used to select which one is required * @size: place to put size value (on success) * - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr_size_index(const struct udevice *dev, int index, fdt_size_t *size); @@ -213,7 +213,7 @@ fdt_addr_t dev_read_addr_size_index(const struct udevice *dev, int index, * @index: the 'reg' property can hold a list of pairs * and @index is used to select which one is required * - * @return pointer or NULL if not found + * Return: pointer or NULL if not found */ void *dev_remap_addr_index(const struct udevice *dev, int index); @@ -225,7 +225,7 @@ void *dev_remap_addr_index(const struct udevice *dev, int index); * 'reg-names' property providing named-based identification. @index * indicates the value to search for in 'reg-names'. * - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name); @@ -238,7 +238,7 @@ fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name); * indicates the value to search for in 'reg-names'. * @size: place to put size value (on success) * - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name, fdt_size_t *size); @@ -252,7 +252,7 @@ fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name, * 'reg-names' property providing named-based identification. @index * indicates the value to search for in 'reg-names'. * - * @return pointer or NULL if not found + * Return: pointer or NULL if not found */ void *dev_remap_addr_name(const struct udevice *dev, const char *name); @@ -261,7 +261,7 @@ void *dev_remap_addr_name(const struct udevice *dev, const char *name); * * @dev: Device to read from * - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr(const struct udevice *dev); @@ -271,7 +271,7 @@ fdt_addr_t dev_read_addr(const struct udevice *dev); * * @dev: Device to read from * - * @return pointer or NULL if not found + * Return: pointer or NULL if not found */ void *dev_read_addr_ptr(const struct udevice *dev); @@ -291,7 +291,7 @@ void *dev_read_addr_ptr(const struct udevice *dev); * fdtdec_get_addr() and friends. * * @dev: Device to read from - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t dev_read_addr_pci(const struct udevice *dev); @@ -301,7 +301,7 @@ fdt_addr_t dev_read_addr_pci(const struct udevice *dev); * * @dev: Device to read from * - * @return pointer or NULL if not found + * Return: pointer or NULL if not found */ void *dev_remap_addr(const struct udevice *dev); @@ -314,7 +314,7 @@ void *dev_remap_addr(const struct udevice *dev); * @dev: Device to read from * @propname: property to read * @sizep: place to put size value (on success) - * @return address value, or FDT_ADDR_T_NONE on error + * Return: address value, or FDT_ADDR_T_NONE on error */ fdt_addr_t dev_read_addr_size(const struct udevice *dev, const char *propname, fdt_size_t *sizep); @@ -323,7 +323,7 @@ fdt_addr_t dev_read_addr_size(const struct udevice *dev, const char *propname, * dev_read_name() - get the name of a device's node * * @dev: Device to read from - * @return name of node + * Return: name of node */ const char *dev_read_name(const struct udevice *dev); @@ -340,12 +340,12 @@ const char *dev_read_name(const struct udevice *dev); * @propname: name of the property containing the string list * @string: string to look up in the string list * - * @return: + * Return: * the index of the string in the list of strings * -ENODATA if the property is not found * -EINVAL on some other error */ -int dev_read_stringlist_search(const struct udevice *dev, const char *property, +int dev_read_stringlist_search(const struct udevice *dev, const char *propname, const char *string); /** @@ -354,9 +354,9 @@ int dev_read_stringlist_search(const struct udevice *dev, const char *property, * @dev: device to examine * @propname: name of the property containing the string list * @index: index of the string to return - * @out: return location for the string + * @outp: return location for the string * - * @return: + * Return: * length of string, if found or -ve error value if not found */ int dev_read_string_index(const struct udevice *dev, const char *propname, @@ -367,7 +367,7 @@ int dev_read_string_index(const struct udevice *dev, const char *propname, * * @dev: device to examine * @propname: name of the property containing the string list - * @return: + * Return: * number of strings in the list, or -ve error value if not found */ int dev_read_string_count(const struct udevice *dev, const char *propname); @@ -386,8 +386,9 @@ int dev_read_string_count(const struct udevice *dev, const char *propname); * @propname: name of the property containing the string list * @listp: returns an allocated, NULL-terminated list of strings if the return * value is > 0, else is set to NULL - * @return number of strings in list, 0 if none, -ENOMEM if out of memory, - * -ENOENT if no such property + * Return: + * number of strings in list, 0 if none, -ENOMEM if out of memory, + * -ENOENT if no such property */ int dev_read_string_list(const struct udevice *dev, const char *propname, const char ***listp); @@ -404,17 +405,17 @@ int dev_read_string_list(const struct udevice *dev, const char *propname, * * Example: * - * phandle1: node1 { - * #list-cells = <2>; - * } + * .. code-block:: * - * phandle2: node2 { - * #list-cells = <1>; - * } - * - * node3 { - * list = <&phandle1 1 2 &phandle2 3>; - * } + * phandle1: node1 { + * #list-cells = <2>; + * }; + * phandle2: node2 { + * #list-cells = <1>; + * }; + * node3 { + * list = <&phandle1 1 2 &phandle2 3>; + * }; * * To get a device_node of the `node2' node you may call this: * dev_read_phandle_with_args(dev, "list", "#list-cells", 0, 1, &args); @@ -422,10 +423,10 @@ int dev_read_string_list(const struct udevice *dev, const char *propname, * @dev: device whose node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count - * @cells_count: Cell count to use if @cells_name is NULL + * @cell_count: Cell count to use if @cells_name is NULL * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) - * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if + * Return: 0 on success (with @out_args filled out if not NULL), -ENOENT if * @list_name does not exist, -EINVAL if a phandle was not found, * @cells_name could not be found, the arguments were truncated or there * were too many arguments. @@ -441,12 +442,11 @@ int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name, * For example, this allows to allocate the right amount of memory to keep * clock's reference contained into the "clocks" property. * - * * @dev: device whose node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count - * @cells_count: Cell count to use if @cells_name is NULL - * @Returns number of phandle found on success, on error returns appropriate + * @cell_count: Cell count to use if @cells_name is NULL + * Return: number of phandle found on success, on error returns appropriate * errno value. */ @@ -461,7 +461,7 @@ int dev_count_phandle_with_args(const struct udevice *dev, * which controls the given node. * * @dev: device to check - * @return number of address cells this node uses + * Return: number of address cells this node uses */ int dev_read_addr_cells(const struct udevice *dev); @@ -472,7 +472,7 @@ int dev_read_addr_cells(const struct udevice *dev); * which controls the given node. * * @dev: device to check - * @return number of size cells this node uses + * Return: number of size cells this node uses */ int dev_read_size_cells(const struct udevice *dev); @@ -482,7 +482,7 @@ int dev_read_size_cells(const struct udevice *dev); * This function matches fdt_address_cells(). * * @dev: device to check - * @return number of address cells this node uses + * Return: number of address cells this node uses */ int dev_read_simple_addr_cells(const struct udevice *dev); @@ -492,7 +492,7 @@ int dev_read_simple_addr_cells(const struct udevice *dev); * This function matches fdt_size_cells(). * * @dev: device to check - * @return number of size cells this node uses + * Return: number of size cells this node uses */ int dev_read_simple_size_cells(const struct udevice *dev); @@ -500,7 +500,7 @@ int dev_read_simple_size_cells(const struct udevice *dev); * dev_read_phandle() - Get the phandle from a device * * @dev: device to check - * @return phandle (1 or greater), or 0 if no phandle or other error + * Return: phandle (1 or greater), or 0 if no phandle or other error */ int dev_read_phandle(const struct udevice *dev); @@ -510,7 +510,7 @@ int dev_read_phandle(const struct udevice *dev); * @dev: device to check * @propname: property to read * @lenp: place to put length on success - * @return pointer to property, or NULL if not found + * Return: pointer to property, or NULL if not found */ const void *dev_read_prop(const struct udevice *dev, const char *propname, int *lenp); @@ -523,7 +523,7 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, * * @dev: device to check * @prop: place to put argument reference - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop); @@ -534,7 +534,7 @@ int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop); * and read all the property with dev_read_prop_by_prop(). * * @prop: reference of current argument and place to put reference of next one - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ int dev_read_next_prop(struct ofprop *prop); @@ -546,7 +546,7 @@ int dev_read_next_prop(struct ofprop *prop); * @prop: reference on property * @propname: If non-NULL, place to property name on success, * @lenp: If non-NULL, place to put length on success - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp); @@ -560,7 +560,7 @@ const void *dev_read_prop_by_prop(struct ofprop *prop, * * @dev: device to look up * @devnump: set to the sequence number if one is found - * @return 0 if a sequence was found, -ve if not + * Return: 0 if a sequence was found, -ve if not */ int dev_read_alias_seq(const struct udevice *dev, int *devnump); @@ -576,7 +576,7 @@ int dev_read_alias_seq(const struct udevice *dev, int *devnump); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read - * @return 0 on success, -EINVAL if the property does not exist, -ENODATA if + * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if * property does not have a value, and -EOVERFLOW if the property data isn't * large enough. */ @@ -587,7 +587,7 @@ int dev_read_u32_array(const struct udevice *dev, const char *propname, * dev_read_first_subnode() - find the first subnode of a device's node * * @dev: device to look up - * @return reference to the first subnode (which can be invalid if the device's + * Return: reference to the first subnode (which can be invalid if the device's * node has no subnodes) */ ofnode dev_read_first_subnode(const struct udevice *dev); @@ -596,7 +596,7 @@ ofnode dev_read_first_subnode(const struct udevice *dev); * ofnode_next_subnode() - find the next sibling of a subnode * * @node: valid reference to previous node (sibling) - * @return reference to the next subnode (which can be invalid if the node + * Return: reference to the next subnode (which can be invalid if the node * has no more siblings) */ ofnode dev_read_next_subnode(ofnode node); @@ -612,8 +612,9 @@ ofnode dev_read_next_subnode(ofnode node); * @dev: device to look up * @propname: name of property to find * @sz: number of array elements - * @return pointer to byte array if found, or NULL if the property is not - * found or there is not enough data + * Return: + * pointer to byte array if found, or NULL if the property is not found or + * there is not enough data */ const uint8_t *dev_read_u8_array_ptr(const struct udevice *dev, const char *propname, size_t sz); @@ -627,7 +628,7 @@ const uint8_t *dev_read_u8_array_ptr(const struct udevice *dev, * by default. * * @dev: device to examine - * @return integer value 0 (not enabled) or 1 (enabled) + * Return: integer value 0 (not enabled) or 1 (enabled) */ int dev_read_enabled(const struct udevice *dev); @@ -635,9 +636,9 @@ int dev_read_enabled(const struct udevice *dev); * dev_read_resource() - obtain an indexed resource from a device. * * @dev: device to examine - * @index index of the resource to retrieve (0 = first) - * @res returns the resource - * @return 0 if ok, negative on error + * @index: index of the resource to retrieve (0 = first) + * @res: returns the resource + * Return: 0 if ok, negative on error */ int dev_read_resource(const struct udevice *dev, uint index, struct resource *res); @@ -648,7 +649,7 @@ int dev_read_resource(const struct udevice *dev, uint index, * @dev: device to examine * @name: name of the resource to retrieve * @res: returns the resource - * @return 0 if ok, negative on error + * Return: 0 if ok, negative on error */ int dev_read_resource_byname(const struct udevice *dev, const char *name, struct resource *res); @@ -662,7 +663,7 @@ int dev_read_resource_byname(const struct udevice *dev, const char *name, * * @dev: device giving the context in which to translate the address * @in_addr: pointer to the address to translate - * @return the translated address; OF_BAD_ADDR on error + * Return: the translated address; OF_BAD_ADDR on error */ u64 dev_translate_address(const struct udevice *dev, const fdt32_t *in_addr); @@ -675,7 +676,7 @@ u64 dev_translate_address(const struct udevice *dev, const fdt32_t *in_addr); * * @dev: device giving the context in which to translate the DMA address * @in_addr: pointer to the DMA address to translate - * @return the translated DMA address; OF_BAD_ADDR on error + * Return: the translated DMA address; OF_BAD_ADDR on error */ u64 dev_translate_dma_address(const struct udevice *dev, const fdt32_t *in_addr); @@ -690,7 +691,7 @@ u64 dev_translate_dma_address(const struct udevice *dev, * @cpu: base address for CPU's view of memory * @bus: base address for BUS's view of memory * @size: size of the address space - * @return 0 if ok, negative on error + * Return: 0 if ok, negative on error */ int dev_get_dma_range(const struct udevice *dev, phys_addr_t *cpu, dma_addr_t *bus, u64 *size); @@ -701,15 +702,15 @@ int dev_get_dma_range(const struct udevice *dev, phys_addr_t *cpu, * * The function travels the lookup table to get the highest alias id for the * given alias stem. - * @return alias ID, if found, else -1 + * Return: alias ID, if found, else -1 */ int dev_read_alias_highest_id(const char *stem); /** * dev_get_child_count() - get the child count of a device * - * @dev: device to use for interation (struct udevice *) - * @return the count of child subnode + * @dev: device to use for interation (`struct udevice *`) + * Return: the count of child subnode */ int dev_get_child_count(const struct udevice *dev); @@ -720,8 +721,8 @@ int dev_get_child_count(const struct udevice *dev); * range for this node. * * @dev: device to examine - * @res returns the resource - * @return 0 if ok, negative on error + * @res: returns the resource + * Return: 0 if ok, negative on error */ int dev_read_pci_bus_range(const struct udevice *dev, struct resource *res); @@ -737,7 +738,7 @@ int dev_read_pci_bus_range(const struct udevice *dev, struct resource *res); * one or more display timing nodes. * @index: index number to read (0=first timing subnode) * @config: place to put timings - * @return 0 if OK, -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -FDT_ERR_NOTFOUND if not found */ int dev_decode_display_timing(const struct udevice *dev, int index, struct display_timing *config); @@ -1100,7 +1101,7 @@ static inline int dev_decode_display_timing(const struct udevice *dev, * device-tree node. * * @subnode: ofnode holding the current subnode - * @dev: device to use for interation (struct udevice *) + * @dev: device to use for interation (`struct udevice *`) */ #define dev_for_each_subnode(subnode, dev) \ for (subnode = dev_read_first_subnode(dev); \ @@ -1114,7 +1115,7 @@ static inline int dev_decode_display_timing(const struct udevice *dev, * device-tree node. * * @prop: struct ofprop holding the current property - * @dev: device to use for interation (struct udevice *) + * @dev: device to use for interation (`struct udevice *`) */ #define dev_for_each_property(prop, dev) \ for (int ret_prop = dev_read_first_prop(dev, &prop); \ From be74f71a679c8ca25a09bea86967dcee8a8b8cae Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:53:49 +0100 Subject: [PATCH 11/28] doc: add include/dm/of*.h to the HTML documentation Correct Sphinx style comments in include/dm/ofnode.h and add the device tree node API to the HTML documentation; the ofnode functions are compatible with Live tree or with flat device tree. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 9 ++ include/dm/of.h | 13 +- include/dm/of_access.h | 139 +++++++++-------- include/dm/of_addr.h | 33 ++--- include/dm/of_extra.h | 48 +++--- include/dm/ofnode.h | 330 +++++++++++++++++++++-------------------- 6 files changed, 297 insertions(+), 275 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 19a473f1f0..5bb66f2f50 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -17,3 +17,12 @@ Device .. kernel-doc:: include/dm/device.h .. kernel-doc:: include/dm/devres.h .. kernel-doc:: include/dm/read.h + +Device tree +----------- + +.. kernel-doc:: include/dm/of.h +.. kernel-doc:: include/dm/ofnode.h +.. kernel-doc:: include/dm/of_extra.h +.. kernel-doc:: include/dm/of_access.h +.. kernel-doc:: include/dm/of_addr.h diff --git a/include/dm/of.h b/include/dm/of.h index 5cb6f44a6c..9c9065b793 100644 --- a/include/dm/of.h +++ b/include/dm/of.h @@ -58,14 +58,13 @@ struct device_node { * struct of_phandle_args - structure to hold phandle and arguments * * This is used when decoding a phandle in a device tree property. Typically - * these look like this: + * these look like this:: * - * wibble { - * phandle = <5>; - * }; - * - * ... - * some-prop = <&wibble 1 2 3> + * wibble { + * phandle = <5>; + * }; + * ... + * some-prop = <&wibble 1 2 3> * * Here &node is the phandle of the node 'wibble', i.e. 5. There are three * arguments: 1, 2, 3. diff --git a/include/dm/of_access.h b/include/dm/of_access.h index cc382b1671..ec6e6e2c7c 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -44,7 +44,7 @@ static inline void of_node_put(const struct device_node *np) { } * which controls the given node. * * @np: Node pointer to check - * @return number of address cells this node uses + * Return: number of address cells this node uses */ int of_n_addr_cells(const struct device_node *np); @@ -55,7 +55,7 @@ int of_n_addr_cells(const struct device_node *np); * which controls the given node. * * @np: Node pointer to check - * @return number of size cells this node uses + * Return: number of size cells this node uses */ int of_n_size_cells(const struct device_node *np); @@ -65,7 +65,7 @@ int of_n_size_cells(const struct device_node *np); * This function matches fdt_address_cells(). * * @np: Node pointer to check - * @return value of #address-cells property in this node, or 2 if none + * Return: value of #address-cells property in this node, or 2 if none */ int of_simple_addr_cells(const struct device_node *np); @@ -75,7 +75,7 @@ int of_simple_addr_cells(const struct device_node *np); * This function matches fdt_size_cells(). * * @np: Node pointer to check - * @return value of #size-cells property in this node, or 2 if none + * Return: value of #size-cells property in this node, or 2 if none */ int of_simple_size_cells(const struct device_node *np); @@ -85,7 +85,7 @@ int of_simple_size_cells(const struct device_node *np); * @np: Pointer to device node holding property * @name: Name of property * @lenp: If non-NULL, returns length of property - * @return pointer to property, or NULL if not found + * Return: pointer to property, or NULL if not found */ struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); @@ -98,7 +98,7 @@ struct property *of_find_property(const struct device_node *np, * @np: Pointer to device node holding property * @name: Name of property * @lenp: If non-NULL, returns length of property - * @return pointer to property value, or NULL if not found + * Return: pointer to property value, or NULL if not found */ const void *of_get_property(const struct device_node *np, const char *name, int *lenp); @@ -110,7 +110,7 @@ const void *of_get_property(const struct device_node *np, const char *name, * and read all the property with of_get_next_property_by_prop(). * * @np: Pointer to device node - * @return pointer to property or NULL if not found + * Return: pointer to property or NULL if not found */ const struct property *of_get_first_property(const struct device_node *np); @@ -122,7 +122,7 @@ const struct property *of_get_first_property(const struct device_node *np); * * @np: Pointer to device node * @property: pointer of the current property - * @return pointer to next property or NULL if not found + * Return: pointer to next property or NULL if not found */ const struct property *of_get_next_property(const struct device_node *np, const struct property *property); @@ -132,11 +132,11 @@ const struct property *of_get_next_property(const struct device_node *np, * * Get value for the property identified by node and property pointer. * - * @node: node to read + * @np: Pointer to device node * @property: pointer of the property to read - * @propname: place to property name on success + * @name: place to property name on success * @lenp: place to put length on success - * @return pointer to property value or NULL if error + * Return: pointer to property value or NULL if error */ const void *of_get_property_by_prop(const struct device_node *np, const struct property *property, @@ -145,7 +145,7 @@ const void *of_get_property_by_prop(const struct device_node *np, /** * of_device_is_compatible() - Check if the node matches given constraints - * @device: pointer to node + * @np: Pointer to device node * @compat: required compatible string, NULL or "" for any match * @type: required device_type value, NULL or "" for any match * @name: required node name, NULL or "" for any match @@ -154,7 +154,7 @@ const void *of_get_property_by_prop(const struct device_node *np, * properties of the given @device. A constraints can be skipped by * passing NULL or an empty string as the constraint. * - * @return 0 for no match, and a positive integer on match. The return + * Return: 0 for no match, and a positive integer on match. The return * value is a relative score with larger values indicating better * matches. The score is weighted for the most specific compatible value * to get the highest score. Matching type is next, followed by matching @@ -179,9 +179,9 @@ int of_device_is_compatible(const struct device_node *np, const char *compat, /** * of_device_is_available() - check if a device is available for use * - * @device: Node to check for availability + * @np: Pointer to device node to check for availability * - * @return true if the status property is absent or set to "okay", false + * Return: true if the status property is absent or set to "okay", false * otherwise */ bool of_device_is_available(const struct device_node *np); @@ -189,8 +189,8 @@ bool of_device_is_available(const struct device_node *np); /** * of_get_parent() - Get a node's parent, if any * - * @node: Node to check - * @eturns a node pointer, or NULL if none + * @np: Pointer to device node to check + * Return: a node pointer, or NULL if none */ struct device_node *of_get_parent(const struct device_node *np); @@ -208,7 +208,7 @@ struct device_node *of_get_parent(const struct device_node *np); * foo Valid alias * foo/bar Valid alias + relative path * - * @return a node pointer or NULL if not found + * Return: a node pointer or NULL if not found */ struct device_node *of_find_node_opts_by_path(const char *path, const char **opts); @@ -228,7 +228,7 @@ static inline struct device_node *of_find_node_by_path(const char *path) * @type: The type string to match "device_type" or NULL to ignore * @compatible: The string to match to one of the tokens in the device * "compatible" list. - * @return node pointer or NULL if not found + * Return: node pointer or NULL if not found */ struct device_node *of_find_compatible_node(struct device_node *from, const char *type, const char *compatible); @@ -243,7 +243,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, * @propname: property name to check * @propval: property value to search for * @proplen: length of the value in propval - * @return node pointer or NULL if not found + * Return: node pointer or NULL if not found */ struct device_node *of_find_node_by_prop_value(struct device_node *from, const char *propname, @@ -254,7 +254,7 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, * * @handle: phandle of the node to find * - * @return node pointer, or NULL if not found + * Return: node pointer, or NULL if not found */ struct device_node *of_find_node_by_phandle(phandle handle); @@ -268,7 +268,7 @@ struct device_node *of_find_node_by_phandle(phandle handle); * @propname: name of the property to be searched. * @outp: pointer to return value, modified only if return value is 0. * - * @return 0 on success, -EINVAL if the property does not exist, + * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. */ @@ -286,9 +286,10 @@ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); * @index: index of the u32 in the list of values * @outp: pointer to return value, modified only if return value is 0. * - * @return 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * Return: + * 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. */ int of_read_u32_index(const struct device_node *np, const char *propname, int index, u32 *outp); @@ -303,9 +304,10 @@ int of_read_u32_index(const struct device_node *np, const char *propname, * @propname: name of the property to be searched. * @outp: pointer to return value, modified only if return value is 0. * - * @return 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * Return: + * 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. */ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); @@ -319,8 +321,9 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read - * @return 0 on success, -EINVAL if the property does not exist, -ENODATA - * if property does not have a value, and -EOVERFLOW is longer than sz. + * Return: + * 0 on success, -EINVAL if the property does not exist, -ENODATA + * if property does not have a value, and -EOVERFLOW is longer than sz. */ int of_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); @@ -334,8 +337,9 @@ int of_read_u32_array(const struct device_node *np, const char *propname, * @np: pointer to node containing string list property * @propname: string list property name * @string: pointer to string to search for in string list - * @return 0 on success, -EINVAL if the property does not exist, -ENODATA - * if property does not have a value, and -EOVERFLOW is longer than sz. + * Return: + * 0 on success, -EINVAL if the property does not exist, -ENODATA + * if property does not have a value, and -EOVERFLOW is longer than sz. */ int of_property_match_string(const struct device_node *np, const char *propname, const char *string); @@ -350,15 +354,17 @@ int of_property_read_string_helper(const struct device_node *np, * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @index: index of the string in the list of strings - * @out_string: pointer to null terminated return string, modified only if + * @output: pointer to null terminated return string, modified only if * return value is 0. * * Search for a property in a device tree node and retrieve a null * terminated string value (pointer to data, not a copy) in the list of strings * contained in that property. - * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if - * property does not have a value, and -EILSEQ if the string is not - * null-terminated within the length of the property data. + * + * Return: + * 0 on success, -EINVAL if the property does not exist, -ENODATA if + * property does not have a value, and -EILSEQ if the string is not + * null-terminated within the length of the property data. * * The out_string pointer is modified only if a valid string can be decoded. */ @@ -377,10 +383,12 @@ static inline int of_property_read_string_index(const struct device_node *np, * @propname: name of the property to be searched. * * Search for a property in a device tree node and retrieve the number of null - * terminated string contain in it. Returns the number of strings on - * success, -EINVAL if the property does not exist, -ENODATA if property - * does not have a value, and -EILSEQ if the string is not null-terminated - * within the length of the property data. + * terminated string contain in it. + * + * Return: + * the number of strings on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EILSEQ if the string is + * not null-terminated within the length of the property data. */ static inline int of_property_count_strings(const struct device_node *np, const char *propname) @@ -395,8 +403,9 @@ static inline int of_property_count_strings(const struct device_node *np, * @index: For properties holding a table of phandles, this is the index into * the table * - * Returns the device_node pointer with refcount incremented. Use - * of_node_put() on it when done. + * Return: + * the device_node pointer with refcount incremented. Use + * of_node_put() on it when done. */ struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index); @@ -410,10 +419,11 @@ struct device_node *of_parse_phandle(const struct device_node *np, * @cells_count: Cell count to use if @cells_name is NULL * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) - * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if - * @list_name does not exist, -EINVAL if a phandle was not found, - * @cells_name could not be found, the arguments were truncated or there - * were too many arguments. + * Return: + * 0 on success (with @out_args filled out if not NULL), -ENOENT if + * @list_name does not exist, -EINVAL if a phandle was not found, + * @cells_name could not be found, the arguments were truncated or there + * were too many arguments. * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_args, on error returns appropriate @@ -424,17 +434,17 @@ struct device_node *of_parse_phandle(const struct device_node *np, * * Example: * - * phandle1: node1 { - * #list-cells = <2>; - * } + * .. code-block:: * - * phandle2: node2 { - * #list-cells = <1>; - * } - * - * node3 { - * list = <&phandle1 1 2 &phandle2 3>; - * } + * phandle1: node1 { + * #list-cells = <2>; + * }; + * phandle2: node2 { + * #list-cells = <1>; + * }; + * node3 { + * list = <&phandle1 1 2 &phandle2 3>; + * }; * * To get a device_node of the `node2' node you may call this: * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); @@ -451,14 +461,13 @@ int of_parse_phandle_with_args(const struct device_node *np, * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * @cells_count: Cell count to use if @cells_name is NULL - * @return number of phandle found, -ENOENT if - * @list_name does not exist, -EINVAL if a phandle was not found, - * @cells_name could not be found, the arguments were truncated or there - * were too many arguments. + * Return: + * number of phandle found, -ENOENT if @list_name does not exist, + * -EINVAL if a phandle was not found, @cells_name could not be found, + * the arguments were truncated or there were too many arguments. * * Returns number of phandle found on success, on error returns appropriate * errno value. - * */ int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, @@ -471,7 +480,7 @@ int of_count_phandle_with_args(const struct device_node *np, * the lookup table with the properties. It returns the number of alias * properties found, or an error code in case of failure. * - * @return 9 if OK, -ENOMEM if not enough memory + * Return: 9 if OK, -ENOMEM if not enough memory */ int of_alias_scan(void); @@ -483,7 +492,7 @@ int of_alias_scan(void); * * @np: Pointer to the given device_node * @stem: Alias stem of the given device_node - * @return alias ID, if found, else -ENODEV + * Return: alias ID, if found, else -ENODEV */ int of_alias_get_id(const struct device_node *np, const char *stem); @@ -493,14 +502,14 @@ int of_alias_get_id(const struct device_node *np, const char *stem); * * The function travels the lookup table to get the highest alias id for the * given alias stem. - * @return alias ID, if found, else -1 + * Return: alias ID, if found, else -1 */ int of_alias_get_highest_id(const char *stem); /** * of_get_stdout() - Get node to use for stdout * - * @return node referred to by stdout-path alias, or NULL if none + * Return: node referred to by stdout-path alias, or NULL if none */ struct device_node *of_get_stdout(void); diff --git a/include/dm/of_addr.h b/include/dm/of_addr.h index ee21d5cf4f..e7f3a28081 100644 --- a/include/dm/of_addr.h +++ b/include/dm/of_addr.h @@ -20,11 +20,11 @@ * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things * - * @np: node to check + * @np: pointer to node to check * @in_addr: pointer to input address - * @return translated address or OF_BAD_ADDR on error + * Return: translated address or OF_BAD_ADDR on error */ -u64 of_translate_address(const struct device_node *no, const __be32 *in_addr); +u64 of_translate_address(const struct device_node *np, const __be32 *in_addr); /** * of_translate_dma_address() - translate a device-tree DMA address to a CPU @@ -38,11 +38,11 @@ u64 of_translate_address(const struct device_node *no, const __be32 *in_addr); * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things * - * @np: node to check + * @np: ne * @in_addr: pointer to input DMA address - * @return translated DMA address or OF_BAD_ADDR on error + * Return: translated DMA address or OF_BAD_ADDR on error */ -u64 of_translate_dma_address(const struct device_node *no, const __be32 *in_addr); +u64 of_translate_dma_address(const struct device_node *np, const __be32 *in_addr); /** @@ -51,14 +51,13 @@ u64 of_translate_dma_address(const struct device_node *no, const __be32 *in_addr * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and * cpu->bus address translations * - * @param blob Pointer to device tree blob - * @param node_offset Node DT offset - * @param cpu Pointer to variable storing the range's cpu address - * @param bus Pointer to variable storing the range's bus address - * @param size Pointer to variable storing the range's size - * @return translated DMA address or OF_BAD_ADDR on error + * @np: Pointer to device tree blob + * @cpu: Pointer to variable storing the range's cpu address + * @bus: Pointer to variable storing the range's bus address + * @size: Pointer to variable storing the range's size + * Return: translated DMA address or OF_BAD_ADDR on error */ -int of_get_dma_range(const struct device_node *dev, phys_addr_t *cpu, +int of_get_dma_range(const struct device_node *np, phys_addr_t *cpu, dma_addr_t *bus, u64 *size); /** @@ -72,9 +71,9 @@ int of_get_dma_range(const struct device_node *dev, phys_addr_t *cpu, * @index: Index of address to read (0 = first) * @size: place to put size on success * @flags: place to put flags on success - * @return pointer to address which can be read + * Return: pointer to address which can be read */ -const __be32 *of_get_address(const struct device_node *no, int index, +const __be32 *of_get_address(const struct device_node *np, int index, u64 *size, unsigned int *flags); struct resource; @@ -90,9 +89,9 @@ struct resource; * @np: node to check * @index: index of address to read (0 = first) * @r: place to put resource information - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ -int of_address_to_resource(const struct device_node *no, int index, +int of_address_to_resource(const struct device_node *np, int index, struct resource *r); #endif diff --git a/include/dm/of_extra.h b/include/dm/of_extra.h index c2498aa585..17e85a819b 100644 --- a/include/dm/of_extra.h +++ b/include/dm/of_extra.h @@ -41,11 +41,11 @@ struct fmap_entry { }; /** - * Read a flash entry from the fdt + * ofnode_read_fmap_entry() - Read a flash entry from the fdt * - * @param node Reference to node to read - * @param entry Place to put offset and size of this node - * @return 0 if ok, -ve on error + * @node: Reference to node to read + * @entry: Place to put offset and size of this node + * Return: 0 if ok, -ve on error */ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry); @@ -58,11 +58,11 @@ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry); * The property must hold one address with a length. This is only tested on * 32-bit machines. * - * @param node ofnode to examine - * @param prop_name name of property to find - * @param basep Returns base address of region - * @param size Returns size of region - * @return 0 if ok, -1 on error (property not found) + * @node: ofnode to examine + * @prop_name: name of property to find + * @basep: Returns base address of region + * @sizep: Returns size of region + * Return: 0 if ok, -1 on error (property not found) */ int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep, fdt_size_t *sizep); @@ -81,14 +81,14 @@ int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep, * The property value must have an offset and a size. The function checks * that the region is entirely within the memory bank.5 * - * @param node ofnode containing the properties (-1 for /config) - * @param mem_type Type of memory to use, which is a name, such as - * "u-boot" or "kernel". - * @param suffix String to append to the memory/offset - * property names - * @param basep Returns base of region - * @param sizep Returns size of region - * @return 0 if OK, -ive on error + * @config_node: ofnode containing the properties (invalid for "/config") + * @mem_type: Type of memory to use, which is a name, such as + * "u-boot" or "kernel". + * @suffix: String to append to the memory/offset + * property names + * @basep: Returns base of region + * @sizep: Returns size of region + * Return: 0 if OK, -ive on error */ int ofnode_decode_memory_region(ofnode config_node, const char *mem_type, const char *suffix, fdt_addr_t *basep, @@ -102,15 +102,15 @@ int ofnode_decode_memory_region(ofnode config_node, const char *mem_type, * * This function supports the following two DT bindings: * - the new DT binding, where 'fixed-link' is a sub-node of the - * Ethernet device + * Ethernet device * - the old DT binding, where 'fixed-link' is a property with 5 - * cells encoding various information about the fixed PHY + * cells encoding various information about the fixed PHY * * If both new and old bindings exist, the new one is preferred. * - * @param eth_node ofnode containing the fixed-link subnode/property - * @param phy_node if fixed-link PHY detected, containing the PHY ofnode - * @return true if a fixed-link pseudo-PHY device exists, false otherwise + * @eth_node: ofnode containing the fixed-link subnode/property + * @phy_node: if fixed-link PHY detected, containing the PHY ofnode + * Return: true if a fixed-link pseudo-PHY device exists, false otherwise */ bool ofnode_phy_is_fixed_link(ofnode eth_node, ofnode *phy_node); @@ -123,8 +123,8 @@ bool ofnode_phy_is_fixed_link(ofnode eth_node, ofnode *phy_node); * is connected to an on-board PHY or an SFP cage, and is not relevant when it * has a fixed link (in that case, in-band autoneg should not be used). * - * @param eth_node ofnode belonging to the Ethernet controller - * @return true if in-band autoneg should be used, false otherwise + * @eth_node: ofnode belonging to the Ethernet controller + * Return: true if in-band autoneg should be used, false otherwise */ bool ofnode_eth_uses_inband_aneg(ofnode eth_node); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 6601bd8318..0cb324c8b0 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -19,7 +19,7 @@ struct resource; /** - * ofnode - reference to a device tree node + * typedef union ofnode_union ofnode - reference to a device tree node * * This union can hold either a straightforward pointer to a struct device_node * in the live device tree, or an offset within the flat device tree. In the @@ -27,7 +27,7 @@ struct resource; * * Thus we can reference nodes in both the live tree (once available) and the * flat tree (until then). Functions are available to translate between an - * ofnode and either an offset or a struct device_node *. + * ofnode and either an offset or a `struct device_node *`. * * The reference can also hold a null offset, in which case the pointer value * here is NULL. This corresponds to a struct device_node * value of @@ -61,7 +61,7 @@ struct ofnode_phandle_args { }; /** - * ofprop - reference to a property of a device tree node + * struct ofprop - reference to a property of a device tree node * * This struct hold the reference on one property of one node, * using struct ofnode and an offset within the flat device tree or either @@ -91,7 +91,7 @@ struct ofprop { * This cannot be called if the reference contains an offset. * * @node: Reference containing struct device_node * (possibly invalid) - * @return pointer to device node (can be NULL) + * Return: pointer to device node (can be NULL) */ static inline const struct device_node *ofnode_to_np(ofnode node) { @@ -108,7 +108,7 @@ static inline const struct device_node *ofnode_to_np(ofnode node) * This cannot be called if the reference contains a node pointer. * * @node: Reference containing offset (possibly invalid) - * @return DT offset (can be -1) + * Return: DT offset (can be -1) */ static inline int ofnode_to_offset(ofnode node) { @@ -122,7 +122,8 @@ static inline int ofnode_to_offset(ofnode node) /** * ofnode_valid() - check if an ofnode is valid * - * @return true if the reference contains a valid ofnode, false if it is NULL + * @node: Reference containing offset (possibly invalid) + * Return: true if the reference contains a valid ofnode, false if it is NULL */ static inline bool ofnode_valid(ofnode node) { @@ -136,7 +137,7 @@ static inline bool ofnode_valid(ofnode node) * offset_to_ofnode() - convert a DT offset to an ofnode * * @of_offset: DT offset (either valid, or -1) - * @return reference to the associated DT offset + * Return: reference to the associated DT offset */ static inline ofnode offset_to_ofnode(int of_offset) { @@ -154,7 +155,7 @@ static inline ofnode offset_to_ofnode(int of_offset) * np_to_ofnode() - convert a node pointer to an ofnode * * @np: Live node pointer (can be NULL) - * @return reference to the associated node pointer + * Return: reference to the associated node pointer */ static inline ofnode np_to_ofnode(const struct device_node *np) { @@ -173,7 +174,7 @@ static inline ofnode np_to_ofnode(const struct device_node *np) * is valid is not permitted. * * @node: reference to check (possibly invalid) - * @return true if the reference is a live node pointer, false if it is a DT + * Return: true if the reference is a live node pointer, false if it is a DT * offset */ static inline bool ofnode_is_np(ofnode node) @@ -193,7 +194,9 @@ static inline bool ofnode_is_np(ofnode node) /** * ofnode_equal() - check if two references are equal * - * @return true if equal, else false + * @ref1: first reference to check (possibly invalid) + * @ref2: second reference to check (possibly invalid) + * Return: true if equal, else false */ static inline bool ofnode_equal(ofnode ref1, ofnode ref2) { @@ -237,28 +240,28 @@ static inline ofnode ofnode_root(void) * * @node: valid node reference that has to be compared * @name: name that has to be compared with the node name - * @return true if matches, false if it doesn't match + * Return: true if matches, false if it doesn't match */ bool ofnode_name_eq(ofnode node, const char *name); /** * ofnode_read_u32() - Read a 32-bit integer from a property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_read_u32(ofnode node, const char *propname, u32 *outp); /** * ofnode_read_u32_index() - Read a 32-bit integer from a multi-value property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @index: index of the integer to return * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_read_u32_index(ofnode node, const char *propname, int index, u32 *outp); @@ -266,47 +269,47 @@ int ofnode_read_u32_index(ofnode node, const char *propname, int index, /** * ofnode_read_s32() - Read a 32-bit integer from a property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ static inline int ofnode_read_s32(ofnode node, const char *propname, - s32 *out_value) + s32 *outp) { - return ofnode_read_u32(node, propname, (u32 *)out_value); + return ofnode_read_u32(node, propname, (u32 *)outp); } /** * ofnode_read_u32_default() - Read a 32-bit integer from a property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ -u32 ofnode_read_u32_default(ofnode ref, const char *propname, u32 def); +u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def); /** * ofnode_read_u32_index_default() - Read a 32-bit integer from a multi-value * property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @index: index of the integer to return * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ -u32 ofnode_read_u32_index_default(ofnode ref, const char *propname, int index, +u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index, u32 def); /** * ofnode_read_s32_default() - Read a 32-bit integer from a property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def); @@ -316,17 +319,17 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def); * @node: valid node reference to read property from * @propname: name of the property to read from * @outp: place to put value (if found) - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp); /** * ofnode_read_u64_default() - Read a 64-bit integer from a property * - * @ref: valid node reference to read property from + * @node: valid node reference to read property from * @propname: name of the property to read from * @def: default value to return if the property has no value - * @return property value, or @def if not found + * Return: property value, or @def if not found */ u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def); @@ -336,8 +339,8 @@ u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def); * @node: valid node reference to read property from * @propname: name of the property to read * @sizep: if non-NULL, returns the size of the property, or an error code - if not found - * @return property value, or NULL if there is no such property + * if not found + * Return: property value, or NULL if there is no such property */ const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep); @@ -346,7 +349,7 @@ const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep); * * @node: valid node reference to read property from * @propname: name of the property to read - * @return string from property value, or NULL if there is no such property + * Return: string from property value, or NULL if there is no such property */ const char *ofnode_read_string(ofnode node, const char *propname); @@ -357,7 +360,7 @@ const char *ofnode_read_string(ofnode node, const char *propname); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error * * Search for a property in a device node and read 32-bit value(s) from * it. Returns 0 on success, -EINVAL if the property does not exist, @@ -374,7 +377,7 @@ int ofnode_read_u32_array(ofnode node, const char *propname, * * @node: valid node reference to read property from * @propname: name of property to read - * @return true if property is present (meaning true), false if not present + * Return: true if property is present (meaning true), false if not present */ bool ofnode_read_bool(ofnode node, const char *propname); @@ -383,7 +386,7 @@ bool ofnode_read_bool(ofnode node, const char *propname); * * @node: valid reference to parent node * @subnode_name: name of subnode to find - * @return reference to subnode (which can be invalid if there is no such + * Return: reference to subnode (which can be invalid if there is no such * subnode) */ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name); @@ -429,7 +432,7 @@ static inline ofnode ofnode_next_subnode(ofnode node) * by default. * * @node: node to examine - * @return false (not enabled) or true (enabled) + * Return: false (not enabled) or true (enabled) */ bool ofnode_is_enabled(ofnode node); @@ -437,7 +440,7 @@ bool ofnode_is_enabled(ofnode node); * ofnode_first_subnode() - find the first subnode of a parent node * * @node: valid reference to a valid parent node - * @return reference to the first subnode (which can be invalid if the parent + * Return: reference to the first subnode (which can be invalid if the parent * node has no subnodes) */ ofnode ofnode_first_subnode(ofnode node); @@ -446,7 +449,7 @@ ofnode ofnode_first_subnode(ofnode node); * ofnode_next_subnode() - find the next sibling of a subnode * * @node: valid reference to previous node (sibling) - * @return reference to the next subnode (which can be invalid if the node + * Return: reference to the next subnode (which can be invalid if the node * has no more siblings) */ ofnode ofnode_next_subnode(ofnode node); @@ -456,7 +459,7 @@ ofnode ofnode_next_subnode(ofnode node); * ofnode_get_parent() - get the ofnode's parent (enclosing ofnode) * * @node: valid node to look up - * @return ofnode reference of the parent node + * Return: ofnode reference of the parent node */ ofnode ofnode_get_parent(ofnode node); @@ -464,7 +467,7 @@ ofnode ofnode_get_parent(ofnode node); * ofnode_get_name() - get the name of a node * * @node: valid node to look up - * @return name of node + * Return: name of node */ const char *ofnode_get_name(ofnode node); @@ -474,7 +477,7 @@ const char *ofnode_get_name(ofnode node); * @node: valid node to look up * @buf: buffer to write the node path into * @buflen: buffer size - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_get_path(ofnode node, char *buf, int buflen); @@ -482,7 +485,7 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); * ofnode_get_by_phandle() - get ofnode from phandle * * @phandle: phandle to look up - * @return ofnode reference to the phandle + * Return: ofnode reference to the phandle */ ofnode ofnode_get_by_phandle(uint phandle); @@ -491,7 +494,7 @@ ofnode ofnode_get_by_phandle(uint phandle); * * @node: node to check * @propname: property to check - * @return size of property if present, or -EINVAL if not + * Return: size of property if present, or -EINVAL if not */ int ofnode_read_size(ofnode node, const char *propname); @@ -504,7 +507,7 @@ int ofnode_read_size(ofnode node, const char *propname); * @node: node to read from * @index: Index of address to read (0 for first) * @size: Pointer to size of the address - * @return address, or FDT_ADDR_T_NONE if not present or invalid + * Return: address, or FDT_ADDR_T_NONE if not present or invalid */ phys_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size); @@ -521,7 +524,7 @@ phys_addr_t ofnode_get_addr_size_index(ofnode node, int index, * @node: node to read from * @index: Index of address to read (0 for first) * @size: Pointer to size of the address - * @return address, or FDT_ADDR_T_NONE if not present or invalid + * Return: address, or FDT_ADDR_T_NONE if not present or invalid */ phys_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index, fdt_size_t *size); @@ -533,7 +536,7 @@ phys_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index, * * @node: node to read from * @index: Index of address to read (0 for first) - * @return address, or FDT_ADDR_T_NONE if not present or invalid + * Return: address, or FDT_ADDR_T_NONE if not present or invalid */ phys_addr_t ofnode_get_addr_index(ofnode node, int index); @@ -543,7 +546,7 @@ phys_addr_t ofnode_get_addr_index(ofnode node, int index); * This reads the register address from a node * * @node: node to read from - * @return address, or FDT_ADDR_T_NONE if not present or invalid + * Return: address, or FDT_ADDR_T_NONE if not present or invalid */ phys_addr_t ofnode_get_addr(ofnode node); @@ -553,7 +556,7 @@ phys_addr_t ofnode_get_addr(ofnode node); * This reads the register size from a node * * @node: node to read from - * @return size of the address, or FDT_SIZE_T_NONE if not present or invalid + * Return: size of the address, or FDT_SIZE_T_NONE if not present or invalid */ fdt_size_t ofnode_get_size(ofnode node); @@ -570,7 +573,7 @@ fdt_size_t ofnode_get_size(ofnode node); * @propname: name of the property containing the string list * @string: string to look up in the string list * - * @return: + * Return: * the index of the string in the list of strings * -ENODATA if the property is not found * -EINVAL on some other error @@ -591,9 +594,9 @@ int ofnode_stringlist_search(ofnode node, const char *propname, * @node: node to check * @propname: name of the property containing the string list * @index: index of the string to return (cannot be negative) - * @lenp: return location for the string length or an error code on failure + * @outp: return location for the string * - * @return: + * Return: * 0 if found or -ve error value if not found */ int ofnode_read_string_index(ofnode node, const char *propname, int index, @@ -603,8 +606,8 @@ int ofnode_read_string_index(ofnode node, const char *propname, int index, * ofnode_read_string_count() - find the number of strings in a string list * * @node: node to check - * @propname: name of the property containing the string list - * @return: + * @property: name of the property containing the string list + * Return: * number of strings in the list, or -ve error value if not found */ int ofnode_read_string_count(ofnode node, const char *property); @@ -620,11 +623,12 @@ int ofnode_read_string_count(ofnode node, const char *property); * changed as they point directly into the devicetree property. * * @node: node to check + * @property: name of the property containing the string list * @listp: returns an allocated, NULL-terminated list of strings if the return * value is > 0, else is set to NULL - * @return number of strings in list, 0 if none, -ENOMEM if out of memory, - * -EINVAL if no such property, -EENODATA if property is empty - * @return: NULL-terminated list of strings (NULL if no property or empty) + * Return: + * number of strings in list, 0 if none, -ENOMEM if out of memory, + * -EINVAL if no such property, -EENODATA if property is empty */ int ofnode_read_string_list(ofnode node, const char *property, const char ***listp); @@ -641,17 +645,17 @@ int ofnode_read_string_list(ofnode node, const char *property, * * Example: * - * phandle1: node1 { - * #list-cells = <2>; - * } + * .. code-block:: * - * phandle2: node2 { - * #list-cells = <1>; - * } - * - * node3 { - * list = <&phandle1 1 2 &phandle2 3>; - * } + * phandle1: node1 { + * #list-cells = <2>; + * }; + * phandle2: node2 { + * #list-cells = <1>; + * }; + * node3 { + * list = <&phandle1 1 2 &phandle2 3>; + * }; * * To get a device_node of the `node2' node you may call this: * ofnode_parse_phandle_with_args(node3, "list", "#list-cells", 0, 1, &args); @@ -659,13 +663,14 @@ int ofnode_read_string_list(ofnode node, const char *property, * @node: device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count - * @cells_count: Cell count to use if @cells_name is NULL + * @cell_count: Cell count to use if @cells_name is NULL * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) - * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if - * @list_name does not exist, -EINVAL if a phandle was not found, - * @cells_name could not be found, the arguments were truncated or there - * were too many arguments. + * Return: + * 0 on success (with @out_args filled out if not NULL), -ENOENT if + * @list_name does not exist, -EINVAL if a phandle was not found, + * @cells_name could not be found, the arguments were truncated or there + * were too many arguments. */ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, const char *cells_name, int cell_count, @@ -682,10 +687,10 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, * @node: device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count - * @cells_count: Cell count to use if @cells_name is NULL - * @return number of phandle on success, -ENOENT if @list_name does not - * exist, -EINVAL if a phandle was not found, @cells_name could not - * be found. + * @cell_count: Cell count to use if @cells_name is NULL + * Return: + * number of phandle on success, -ENOENT if @list_name does not exist, + * -EINVAL if a phandle was not found, @cells_name could not be found. */ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, const char *cells_name, int cell_count); @@ -694,7 +699,7 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, * ofnode_path() - find a node by full path * * @path: Full path to node, e.g. "/bus/spi@1" - * @return reference to the node found. Use ofnode_valid() to check if it exists + * Return: reference to the node found. Use ofnode_valid() to check if it exists */ ofnode ofnode_path(const char *path); @@ -704,9 +709,9 @@ ofnode ofnode_path(const char *path); * This looks for a property within the /chosen node and returns its value * * @propname: Property name to look for - * @sizep: Returns size of property, or FDT_ERR_... error code if function + * @sizep: Returns size of property, or `FDT_ERR_...` error code if function * returns NULL - * @return property value if found, else NULL + * Return: property value if found, else NULL */ const void *ofnode_read_chosen_prop(const char *propname, int *sizep); @@ -717,7 +722,7 @@ const void *ofnode_read_chosen_prop(const char *propname, int *sizep); * checking that it is a valid nul-terminated string * * @propname: Property name to look for - * @return string value if found, else NULL + * Return: string value if found, else NULL */ const char *ofnode_read_chosen_string(const char *propname); @@ -727,7 +732,8 @@ const char *ofnode_read_chosen_string(const char *propname); * This looks up a named property in the chosen node and uses that as a path to * look up a code. * - * @return the referenced node if present, else ofnode_null() + * @propname: Property name to look for + * Return: the referenced node if present, else ofnode_null() */ ofnode ofnode_get_chosen_node(const char *propname); @@ -737,9 +743,9 @@ ofnode ofnode_get_chosen_node(const char *propname); * This looks for a property within the /aliases node and returns its value * * @propname: Property name to look for - * @sizep: Returns size of property, or FDT_ERR_... error code if function + * @sizep: Returns size of property, or `FDT_ERR_...` error code if function * returns NULL - * @return property value if found, else NULL + * Return: property value if found, else NULL */ const void *ofnode_read_aliases_prop(const char *propname, int *sizep); @@ -749,7 +755,8 @@ const void *ofnode_read_aliases_prop(const char *propname, int *sizep); * This looks up a named property in the aliases node and uses that as a path to * look up a code. * - * @return the referenced node if present, else ofnode_null() + * @propname: Property name to look for + * Return: the referenced node if present, else ofnode_null() */ ofnode ofnode_get_aliases_node(const char *propname); @@ -761,10 +768,10 @@ struct display_timing; * See doc/device-tree-bindings/video/display-timing.txt for binding * information. * - * @node 'display-timing' node containing the timing subnodes - * @index Index number to read (0=first timing subnode) - * @config Place to put timings - * @return 0 if OK, -FDT_ERR_NOTFOUND if not found + * @node: 'display-timing' node containing the timing subnodes + * @index: Index number to read (0=first timing subnode) + * @config: Place to put timings + * Return: 0 if OK, -FDT_ERR_NOTFOUND if not found */ int ofnode_decode_display_timing(ofnode node, int index, struct display_timing *config); @@ -775,7 +782,7 @@ int ofnode_decode_display_timing(ofnode node, int index, * @node: node to read * @propname: property to read * @lenp: place to put length on success - * @return pointer to property, or NULL if not found + * Return: pointer to property, or NULL if not found */ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); @@ -787,7 +794,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); * * @node: node to read * @prop: place to put argument reference - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ int ofnode_get_first_property(ofnode node, struct ofprop *prop); @@ -798,7 +805,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop); * and read all the property with ofnode_get_property_by_prop(). * * @prop: reference of current argument and place to put reference of next one - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ int ofnode_get_next_property(struct ofprop *prop); @@ -810,7 +817,7 @@ int ofnode_get_next_property(struct ofprop *prop); * @prop: reference on property * @propname: If non-NULL, place to property name on success, * @lenp: If non-NULL, place to put length on success - * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ const void *ofnode_get_property_by_prop(const struct ofprop *prop, const char **propname, int *lenp); @@ -819,7 +826,7 @@ const void *ofnode_get_property_by_prop(const struct ofprop *prop, * ofnode_is_available() - check if a node is marked available * * @node: node to check - * @return true if node's 'status' property is "okay" (or is missing) + * Return: true if node's 'status' property is "okay" (or is missing) */ bool ofnode_is_available(ofnode node); @@ -832,7 +839,7 @@ bool ofnode_is_available(ofnode node); * @node: node to read from * @propname: property to read * @sizep: place to put size value (on success) - * @return address value, or FDT_ADDR_T_NONE on error + * Return: address value, or FDT_ADDR_T_NONE on error */ phys_addr_t ofnode_get_addr_size(ofnode node, const char *propname, phys_size_t *sizep); @@ -845,11 +852,12 @@ phys_addr_t ofnode_get_addr_size(ofnode node, const char *propname, * for the array (count bytes). It may have more, but this will be ignored. * The data is not copied. * - * @node node to examine - * @propname name of property to find - * @sz number of array elements - * @return pointer to byte array if found, or NULL if the property is not - * found or there is not enough data + * @node: node to examine + * @propname: name of property to find + * @sz: number of array elements + * Return: + * pointer to byte array if found, or NULL if the property is not found or + * there is not enough data */ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, size_t sz); @@ -861,13 +869,14 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, * corresponds to the given type in the form of fdt_pci_addr. * The property must hold one fdt_pci_addr with a lengh. * - * @node node to examine - * @type pci address type (FDT_PCI_SPACE_xxx) - * @propname name of property to find - * @addr returns pci address in the form of fdt_pci_addr - * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the - * format of the property was invalid, -ENXIO if the requested - * address type was not found + * @node: node to examine + * @type: pci address type (FDT_PCI_SPACE_xxx) + * @propname: name of property to find + * @addr: returns pci address in the form of fdt_pci_addr + * Return: + * 0 if ok, -ENOENT if the property did not exist, -EINVAL if the + * format of the property was invalid, -ENXIO if the requested + * address type was not found */ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type, const char *propname, struct fdt_pci_addr *addr); @@ -878,10 +887,10 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type, * Look at the compatible property of a device node that represents a PCI * device and extract pci vendor id and device id from it. * - * @param node node to examine - * @param vendor vendor id of the pci device - * @param device device id of the pci device - * @return 0 if ok, negative on error + * @node: node to examine + * @vendor: vendor id of the pci device + * @device: device id of the pci device + * Return: 0 if ok, negative on error */ int ofnode_read_pci_vendev(ofnode node, u16 *vendor, u16 *device); @@ -892,7 +901,7 @@ int ofnode_read_pci_vendev(ofnode node, u16 *vendor, u16 *device); * which controls the given node. * * @node: Node to check - * @return number of address cells this node uses + * Return: number of address cells this node uses */ int ofnode_read_addr_cells(ofnode node); @@ -903,7 +912,7 @@ int ofnode_read_addr_cells(ofnode node); * which controls the given node. * * @node: Node to check - * @return number of size cells this node uses + * Return: number of size cells this node uses */ int ofnode_read_size_cells(ofnode node); @@ -912,8 +921,8 @@ int ofnode_read_size_cells(ofnode node); * * This function matches fdt_address_cells(). * - * @np: Node pointer to check - * @return value of #address-cells property in this node, or 2 if none + * @node: Node to check + * Return: value of #address-cells property in this node, or 2 if none */ int ofnode_read_simple_addr_cells(ofnode node); @@ -922,8 +931,8 @@ int ofnode_read_simple_addr_cells(ofnode node); * * This function matches fdt_size_cells(). * - * @np: Node pointer to check - * @return value of #size-cells property in this node, or 2 if none + * @node: Node to check + * Return: value of #size-cells property in this node, or 2 if none */ int ofnode_read_simple_size_cells(ofnode node); @@ -942,14 +951,13 @@ int ofnode_read_simple_size_cells(ofnode node); * There are 4 settings currently in use * - u-boot,dm-pre-proper: U-Boot proper pre-relocation only * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL - * Existing platforms only use it to indicate nodes needed in - * SPL. Should probably be replaced by u-boot,dm-spl for - * new platforms. + * Existing platforms only use it to indicate nodes needed in + * SPL. Should probably be replaced by u-boot,dm-spl for new platforms. * - u-boot,dm-spl: SPL and U-Boot pre-relocation * - u-boot,dm-tpl: TPL and U-Boot pre-relocation * * @node: node to check - * @return true if node is needed in SPL/TL, false otherwise + * Return: true if node is needed in SPL/TL, false otherwise */ bool ofnode_pre_reloc(ofnode node); @@ -961,7 +969,7 @@ bool ofnode_pre_reloc(ofnode node); * @node: Node to read from * @index: Index of resource to read (0 = first) * @res: Returns resource that was read, on success - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_read_resource(ofnode node, uint index, struct resource *res); @@ -975,7 +983,7 @@ int ofnode_read_resource(ofnode node, uint index, struct resource *res); * @node: Node to read from * @name: Name of resource to read * @res: Returns resource that was read, on success - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ int ofnode_read_resource_byname(ofnode node, const char *name, struct resource *res); @@ -987,7 +995,7 @@ int ofnode_read_resource_byname(ofnode node, const char *name, * * @from: ofnode to start from (use ofnode_null() to start at the beginning) * @compat: Compatible string to match - * @return ofnode found, or ofnode_null() if none + * Return: ofnode found, or ofnode_null() if none */ ofnode ofnode_by_compatible(ofnode from, const char *compat); @@ -998,9 +1006,11 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat); * @propval and a length @proplen. * * @from: ofnode to start from (use ofnode_null() to start at the - * beginning) @propname: property name to check @propval: property value to - * search for @proplen: length of the value in propval @return ofnode - * found, or ofnode_null() if none + * beginning) + * @propname: property name to check + * @propval: property value to search for + * @proplen: length of the value in propval + * Return: ofnode found, or ofnode_null() if none */ ofnode ofnode_by_prop_value(ofnode from, const char *propname, const void *propval, int proplen); @@ -1011,14 +1021,13 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, * @node: child node (ofnode, lvalue) * @parent: parent node (ofnode) * - * This is a wrapper around a for loop and is used like so: + * This is a wrapper around a for loop and is used like so:: * - * ofnode node; - * - * ofnode_for_each_subnode(node, parent) { - * Use node - * ... - * } + * ofnode node; + * ofnode_for_each_subnode(node, parent) { + * Use node + * ... + * } * * Note that this is implemented as a macro and @node is used as * iterator in the loop. The parent variable can be a constant or even a @@ -1036,14 +1045,13 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, * @node: child node (ofnode, lvalue) * @compat: compatible string to match * - * This is a wrapper around a for loop and is used like so: + * This is a wrapper around a for loop and is used like so:: * - * ofnode node; - * - * ofnode_for_each_compatible_node(node, parent, compatible) { - * Use node - * ... - * } + * ofnode node; + * ofnode_for_each_compatible_node(node, parent, compatible) { + * Use node + * ... + * } * * Note that this is implemented as a macro and @node is used as * iterator in the loop. @@ -1056,8 +1064,8 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, /** * ofnode_get_child_count() - get the child count of a ofnode * - * @node: valid node to get its child count - * @return the number of subnodes + * @parent: valid node to get its child count + * Return: the number of subnodes */ int ofnode_get_child_count(ofnode parent); @@ -1068,10 +1076,9 @@ int ofnode_get_child_count(ofnode parent); * function walks up the tree and applies the various bus mappings along the * way. * - * @ofnode: Device tree node giving the context in which to translate the - * address + * @node: Device tree node giving the context in which to translate the address * @in_addr: pointer to the address to translate - * @return the translated address; OF_BAD_ADDR on error + * Return: the translated address; OF_BAD_ADDR on error */ u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr); @@ -1082,10 +1089,10 @@ u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr); * This function walks up the tree and applies the various bus mappings along * the way. * - * @ofnode: Device tree node giving the context in which to translate the - * DMA address + * @node: Device tree node giving the context in which to translate the + * DMA address * @in_addr: pointer to the DMA address to translate - * @return the translated DMA address; OF_BAD_ADDR on error + * Return: the translated DMA address; OF_BAD_ADDR on error */ u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr); @@ -1095,12 +1102,11 @@ u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr); * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and * cpu->bus address translations * - * @param blob Pointer to device tree blob - * @param node_offset Node DT offset - * @param cpu Pointer to variable storing the range's cpu address - * @param bus Pointer to variable storing the range's bus address - * @param size Pointer to variable storing the range's size - * @return translated DMA address or OF_BAD_ADDR on error + * @node: Device tree node + * @cpu: Pointer to variable storing the range's cpu address + * @bus: Pointer to variable storing the range's bus address + * @size: Pointer to variable storing the range's size + * Return: translated DMA address or OF_BAD_ADDR on error */ int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size); @@ -1112,7 +1118,7 @@ int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, * * @node: Device tree node for which compatible needs to be verified. * @compat: Compatible string which needs to verified in the given node. - * @return true if OK, false if the compatible is not found + * Return: true if OK, false if the compatible is not found */ int ofnode_device_is_compatible(ofnode node, const char *compat); @@ -1127,7 +1133,7 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); * @len: The length of the new value of the property * @value: The new value of the property (must be valid prior to calling * the function) - * @return 0 if successful, -ve on error + * Return: 0 if successful, -ve on error */ int ofnode_write_prop(ofnode node, const char *propname, int len, const void *value); @@ -1142,7 +1148,7 @@ int ofnode_write_prop(ofnode node, const char *propname, int len, * @propname: The name of the string property to set * @value: The new value of the string property (must be valid prior to * calling the function) - * @return 0 if successful, -ve on error + * Return: 0 if successful, -ve on error */ int ofnode_write_string(ofnode node, const char *propname, const char *value); @@ -1157,7 +1163,7 @@ int ofnode_write_string(ofnode node, const char *propname, const char *value); * @node: The node to enable * @value: Flag that tells the function to either disable or enable the * node - * @return 0 if successful, -ve on error + * Return: 0 if successful, -ve on error */ int ofnode_set_enabled(ofnode node, bool value); @@ -1168,8 +1174,8 @@ int ofnode_set_enabled(ofnode node, bool value); * * See doc/config.txt for bindings * - * @prop_name property name to look up - * @return true, if it exists, false if not + * @prop_name: property name to look up + * Return: true, if it exists, false if not */ bool ofnode_conf_read_bool(const char *prop_name); @@ -1182,7 +1188,7 @@ bool ofnode_conf_read_bool(const char *prop_name); * * @prop_name: property name to look up * @default_val: default value to return if the property is not found - * @return integer value, if found, or @default_val if not + * Return: integer value, if found, or @default_val if not */ int ofnode_conf_read_int(const char *prop_name, int default_val); @@ -1194,7 +1200,7 @@ int ofnode_conf_read_int(const char *prop_name, int default_val); * See doc/config.txt for bindings * * @prop_name: property name to look up - * @return string value, if found, or NULL if not + * Return: string value, if found, or NULL if not */ const char *ofnode_conf_read_str(const char *prop_name); From 5ebb52702edeeb2b46699ead31c56a7a5a127b49 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 12 Jan 2022 10:55:41 +0100 Subject: [PATCH 12/28] doc: add include/dm/fdtaddr.h to the HTML documentation Correct Sphinx style comments in include/dm/fdtaddr.h and add the devfdt API to the HTML documentation; these functions are NOT compatible with live tree. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt --- doc/api/dm.rst | 1 + include/dm/fdtaddr.h | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/api/dm.rst b/doc/api/dm.rst index 5bb66f2f50..df605dae9d 100644 --- a/doc/api/dm.rst +++ b/doc/api/dm.rst @@ -26,3 +26,4 @@ Device tree .. kernel-doc:: include/dm/of_extra.h .. kernel-doc:: include/dm/of_access.h .. kernel-doc:: include/dm/of_addr.h +.. kernel-doc:: include/dm/fdtaddr.h diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h index d2c1994291..c9d2b27ba6 100644 --- a/include/dm/fdtaddr.h +++ b/include/dm/fdtaddr.h @@ -19,7 +19,7 @@ struct udevice; * * @dev: Pointer to a device * - * @return addr + * Return: addr */ fdt_addr_t devfdt_get_addr(const struct udevice *dev); @@ -29,7 +29,7 @@ fdt_addr_t devfdt_get_addr(const struct udevice *dev); * * @dev: Pointer to a device * - * @return Pointer to addr, or NULL if there is no such property + * Return: Pointer to addr, or NULL if there is no such property */ void *devfdt_get_addr_ptr(const struct udevice *dev); @@ -39,7 +39,7 @@ void *devfdt_get_addr_ptr(const struct udevice *dev); * * @dev: Pointer to a device * - * @return Pointer to addr, or NULL if there is no such property + * Return: Pointer to addr, or NULL if there is no such property */ void *devfdt_remap_addr(const struct udevice *dev); @@ -51,7 +51,7 @@ void *devfdt_remap_addr(const struct udevice *dev); * * @dev: Pointer to a device * - * @return Pointer to addr, or NULL if there is no such property + * Return: Pointer to addr, or NULL if there is no such property */ void *devfdt_remap_addr_index(const struct udevice *dev, int index); @@ -64,7 +64,7 @@ void *devfdt_remap_addr_index(const struct udevice *dev, int index); * * @dev: Pointer to a device * - * @return Pointer to addr, or NULL if there is no such property + * Return: Pointer to addr, or NULL if there is no such property */ void *devfdt_remap_addr_name(const struct udevice *dev, const char *name); @@ -76,8 +76,7 @@ void *devfdt_remap_addr_name(const struct udevice *dev, const char *name); * @dev: Pointer to device * @size: size of the memory to map * - * @return mapped address, or NULL if the device does not have reg - * property. + * Return: mapped address, or NULL if the device does not have reg property. */ void *devfdt_map_physmem(const struct udevice *dev, unsigned long size); @@ -88,7 +87,7 @@ void *devfdt_map_physmem(const struct udevice *dev, unsigned long size); * @index: the 'reg' property can hold a list of pairs * and @index is used to select which one is required * - * @return addr + * Return: addr */ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index); @@ -100,7 +99,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index); * @index: the 'reg' property can hold a list of pairs * and @index is used to select which one is required * - * @return Pointer to addr, or NULL if there is no such property + * Return: Pointer to addr, or NULL if there is no such property */ void *devfdt_get_addr_index_ptr(const struct udevice *dev, int index); @@ -115,7 +114,7 @@ void *devfdt_get_addr_index_ptr(const struct udevice *dev, int index); * @size: Pointer to size varible - this function returns the size * specified in the 'reg' property here * - * @return addr + * Return: addr */ fdt_addr_t devfdt_get_addr_size_index(const struct udevice *dev, int index, fdt_size_t *size); @@ -128,7 +127,7 @@ fdt_addr_t devfdt_get_addr_size_index(const struct udevice *dev, int index, * 'reg-names' property providing named-based identification. @index * indicates the value to search for in 'reg-names'. * - * @return addr + * Return: addr */ fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name); @@ -145,7 +144,7 @@ fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name); * @size: Pointer to size variable - this function returns the size * specified in the 'reg' property here * - * @return addr + * Return: addr */ fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev, const char *name, fdt_size_t *size); @@ -154,7 +153,7 @@ fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev, * devfdt_get_addr_pci() - Read an address and handle PCI address translation * * @dev: Device to read from - * @return address or FDT_ADDR_T_NONE if not found + * Return: address or FDT_ADDR_T_NONE if not found */ fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev); From dfbc2be47edcb5190d161390b50d2dcc5086710e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 9 Jan 2022 18:16:11 +0100 Subject: [PATCH 13/28] riscv: revert Complete efi header for RV32/64 EDK II refuses to load the EFI binaries created by U-Boot. The reason is an incorrect PE-COFF header. The number of data directories does not match NumberOfRvaAndSizes. This leads to a failed consistency check in PeCoffLoaderGetPeHeader(): SizeOfOptionalHeader - HeaderWithoutDataDir) != NumberOfRvaAndSizes * sizeof(DATA_DIRECTORY)) Fixes: 9afaeec6ef8b ("riscv: Complete efi header for RV32/64") Signed-off-by: Heinrich Schuchardt --- arch/riscv/lib/crt0_riscv_efi.S | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index b0a7a39a72..3e62e8e67b 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -110,16 +110,6 @@ extra_header_fields: .quad 0 /* ExceptionTable */ .quad 0 /* CertificationTable */ .quad 0 /* BaseRelocationTable */ - .quad 0 /* Debug */ - .quad 0 /* Architecture */ - .quad 0 /* Global Ptr */ - .quad 0 /* TLS Table */ - .quad 0 /* Load Config Table */ - .quad 0 /* Bound Import */ - .quad 0 /* IAT */ - .quad 0 /* Delay Import Descriptor */ - .quad 0 /* CLR Runtime Header */ - .quad 0 /* Reserved */ /* Section table */ section_table: From 9ef5ccaa712238f4ccd3c55f8a7ae6ca28a5a5bf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 14 Jan 2022 21:40:15 +0100 Subject: [PATCH 14/28] efi_loader: fix SectionAlignment, FileAlignment The alignment of sections in the EFI binaries generated by U-Boot is incorrect. According to the PE-COFF specification [1] the minimum value for FileAlignment is 512. If the value of SectionAlignment is less then the page size, it must equal FileAlignment. Let's set both values to 512 for the ARM and RISC-V architectures. [1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/crt0_aarch64_efi.S | 5 +++-- arch/arm/lib/crt0_arm_efi.S | 5 +++-- arch/arm/lib/elf_aarch64_efi.lds | 4 ++-- arch/arm/lib/elf_arm_efi.lds | 4 ++-- arch/riscv/lib/crt0_riscv_efi.S | 5 +++-- arch/riscv/lib/elf_riscv32_efi.lds | 4 ++-- arch/riscv/lib/elf_riscv64_efi.lds | 4 ++-- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S index 492195f765..7f38465359 100644 --- a/arch/arm/lib/crt0_aarch64_efi.S +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -47,8 +47,8 @@ optional_header: extra_header_fields: .quad 0 /* ImageBase */ - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 0 /* MajorImageVersion */ @@ -117,6 +117,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: stp x29, x30, [sp, #-32]! mov x29, sp diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S index cc8a115f31..75ee37b7d3 100644 --- a/arch/arm/lib/crt0_arm_efi.S +++ b/arch/arm/lib/crt0_arm_efi.S @@ -47,8 +47,8 @@ optional_header: extra_header_fields: .long 0 /* image_base */ - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 0 /* MajorImageVersion */ @@ -115,6 +115,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: stmfd sp!, {r0-r2, lr} diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds index 90af469f48..c0604dad46 100644 --- a/arch/arm/lib/elf_aarch64_efi.lds +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -18,7 +18,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -44,7 +44,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds index d6d742e868..767ebda635 100644 --- a/arch/arm/lib/elf_arm_efi.lds +++ b/arch/arm/lib/elf_arm_efi.lds @@ -18,7 +18,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -44,7 +44,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index 3e62e8e67b..a01e08a3c6 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -71,8 +71,8 @@ extra_header_fields: #else .quad 0 /* ImageBase */ #endif - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 1 /* MajorImageVersion */ @@ -148,6 +148,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: addi sp, sp, -(SIZE_LONG * 3) SAVE_LONG(a0, 0) diff --git a/arch/riscv/lib/elf_riscv32_efi.lds b/arch/riscv/lib/elf_riscv32_efi.lds index 629705fc28..c3e0d20d57 100644 --- a/arch/riscv/lib/elf_riscv32_efi.lds +++ b/arch/riscv/lib/elf_riscv32_efi.lds @@ -20,7 +20,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -46,7 +46,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/riscv/lib/elf_riscv64_efi.lds b/arch/riscv/lib/elf_riscv64_efi.lds index aece030c37..ecb9139548 100644 --- a/arch/riscv/lib/elf_riscv64_efi.lds +++ b/arch/riscv/lib/elf_riscv64_efi.lds @@ -20,7 +20,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -46,7 +46,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } From 504dbd224a5fd4f80b785e17c106ea738cd32cb4 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 11 Jan 2022 15:43:05 +0100 Subject: [PATCH 15/28] disk: gpt: print all partitions For GPT partition tables the 'part list' command stops at the first invalid partition number. But Ubuntu has images with partitions number 1, 12, 13, 14, 15 In this case only partition 1 was listed by 'part list'. Fixes: 38a3021edc54 ("disk: part_efi: remove indent level from loop") Reported-by: Alexandre Ghiti Signed-off-by: Heinrich Schuchardt Tested-by: Alexandre Ghiti --- disk/part_efi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/disk/part_efi.c b/disk/part_efi.c index 0ca7effc32..3809333078 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -236,9 +236,9 @@ void part_print_efi(struct blk_desc *dev_desc) printf("\tPartition GUID\n"); for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) { - /* Stop at the first non valid PTE */ + /* Skip invalid PTE */ if (!is_pte_valid(&gpt_pte[i])) - break; + continue; printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1), le64_to_cpu(gpt_pte[i].starting_lba), From bc314f8e5f9b646e5ed09ccee2a2ddb012519305 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 11 Jan 2022 16:03:38 +0100 Subject: [PATCH 16/28] cmd: part: list all 128 GPT partitions A GPT partition table typically has 128 entries. If a partition table contains a partition 128 'part list' should be able to list it. Signed-off-by: Heinrich Schuchardt --- cmd/part.c | 4 ++-- include/part.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/part.c b/cmd/part.c index e0463b5a54..9d419c967c 100644 --- a/cmd/part.c +++ b/cmd/part.c @@ -89,10 +89,10 @@ static int do_part_list(int argc, char *const argv[]) if (var != NULL) { int p; - char str[512] = { '\0', }; + char str[3 * MAX_SEARCH_PARTITIONS] = { '\0', }; struct disk_partition info; - for (p = 1; p < MAX_SEARCH_PARTITIONS; p++) { + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { char t[5]; int r = part_get_info(desc, p, &info); diff --git a/include/part.h b/include/part.h index b66b07a1f0..b8d8e1ff0d 100644 --- a/include/part.h +++ b/include/part.h @@ -50,7 +50,7 @@ struct block_drvr { #define PART_NAME_LEN 32 #define PART_TYPE_LEN 32 -#define MAX_SEARCH_PARTITIONS 64 +#define MAX_SEARCH_PARTITIONS 128 #define PART_BOOTABLE ((int)BIT(0)) #define PART_EFI_SYSTEM_PARTITION ((int)BIT(1)) From a2f1482fc0e6c5dbdbafecd360d168f9c12fc529 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Mon, 3 Jan 2022 14:07:37 +0200 Subject: [PATCH 17/28] efi_loader: Get rid of kaslr-seed if EFI_RNG_PROTOCOL is installed U-Boot, in some occasions, injects a 'kaslr-seed' property on the /chosen node. That would be problematic in case we want to measure the DTB we install in the configuration table, since it would change across reboots. The Linux kernel EFI-stub completely ignores it and only relies on EFI_RNG_PROTOCOL for it's own randomness needs (i.e the randomization of the physical placement of the kernel). In fact it (blindly) overwrites the existing seed if the protocol is installed. However it still uses it for randomizing it's virtual placement. So let's get rid of it in the presence of the RNG protocol. It's worth noting that TPMs also provide an RNG. So if we tweak our EFI_RNG_PROTOCOL slightly and install the protocol when a TPM device is present the 'kaslr-seed' property will always be removed, allowing us to reliably measure our DTB. Acked-by: Ard Biesheuvel Signed-off-by: Ilias Apalodimas Reviewed-by: Mark Kettenis --- cmd/bootefi.c | 2 ++ include/efi_loader.h | 2 ++ lib/efi_loader/efi_dt_fixup.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 83eab0bd7f..3a8b2b6061 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -310,6 +310,8 @@ efi_status_t efi_install_fdt(void *fdt) /* Create memory reservations as indicated by the device tree */ efi_carve_out_dt_rsv(fdt); + efi_try_purge_kaslr_seed(fdt); + /* Install device tree as UEFI table */ ret = efi_install_configuration_table(&efi_guid_fdt, fdt); if (ret != EFI_SUCCESS) { diff --git a/include/efi_loader.h b/include/efi_loader.h index f4860e87fc..f20d361876 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -517,6 +517,8 @@ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition, void **address); /* Carve out DT reserved memory ranges */ void efi_carve_out_dt_rsv(void *fdt); +/* Purge unused kaslr-seed */ +void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); /* Called by bootefi to make all disk storage accessible as EFI objects */ diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index b6fe5d2e5a..d3923e5dba 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,38 @@ static void efi_reserve_memory(u64 addr, u64 size, bool nomap) addr, size); } +/** + * efi_try_purge_kaslr_seed() - Remove unused kaslr-seed + * + * Kernel's EFI STUB only relies on EFI_RNG_PROTOCOL for randomization + * and completely ignores the kaslr-seed for its own randomness needs + * (i.e the randomization of the physical placement of the kernel). + * Weed it out from the DTB we hand over, which would mess up our DTB + * TPM measurements as well. + * + * @fdt: Pointer to device tree + */ +void efi_try_purge_kaslr_seed(void *fdt) +{ + const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID; + struct efi_handler *handler; + efi_status_t ret; + int nodeoff = 0; + int err = 0; + + ret = efi_search_protocol(efi_root, &efi_guid_rng_protocol, &handler); + if (ret != EFI_SUCCESS) + return; + + nodeoff = fdt_path_offset(fdt, "/chosen"); + if (nodeoff < 0) + return; + + err = fdt_delprop(fdt, nodeoff, "kaslr-seed"); + if (err < 0 && err != -FDT_ERR_NOTFOUND) + log_err("Error deleting kaslr-seed\n"); +} + /** * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges * From 717b33cb9b51ec70a3795783eaf02836bfa9b098 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Jan 2022 02:11:22 +0100 Subject: [PATCH 18/28] efidebug: avoid 'dfu_alt_info not defined' message If variable dfu_alt_info is not defined duplicate messages are displayed. => efidebug boot dump Scanning disk mmc2.blk... Scanning disk mmc1.blk... Scanning disk mmc0.blk... Found 3 disks No EFI system partition "dfu_alt_info" env variable not defined! Probably dfu_alt_info not defined "dfu_alt_info" env variable not defined! Probably dfu_alt_info not defined Remove the 'Probably dfu_alt_info not defined' message. Instead write a warning if the variable contains no entities. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_firmware.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a1b88dbfc2..519a47267c 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -128,8 +128,11 @@ static efi_status_t efi_get_dfu_info( size_t names_len, total_size; int dfu_num, i; u16 *name, *next; + int ret; - dfu_init_env_entities(NULL, NULL); + ret = dfu_init_env_entities(NULL, NULL); + if (ret) + return EFI_SUCCESS; names_len = 0; dfu_num = 0; @@ -138,7 +141,7 @@ static efi_status_t efi_get_dfu_info( dfu_num++; } if (!dfu_num) { - log_warning("Probably dfu_alt_info not defined\n"); + log_warning("No entities in dfu_alt_info\n"); *image_info_size = 0; dfu_free_entities(); From bf59c46bcb51251442a8366005b31f6f8528a780 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Jan 2022 02:20:02 +0100 Subject: [PATCH 19/28] MAINTAINERS: remove Alexander Graf from EFI PAYLOAD The last review by Alex was in 2019. Signed-off-by: Heinrich Schuchardt --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6ae81c5659..38c68ee87d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -737,7 +737,6 @@ F: test/dm/efi_media.c EFI PAYLOAD M: Heinrich Schuchardt -R: Alexander Graf S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git F: doc/api/efi.rst From 866e2ac5aa4b8a36db5bb4afd8b4e8302029849a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:10 -0700 Subject: [PATCH 20/28] efi: Move exit_boot_services into a function At present this code is inline in the app and stub. But they do the same thing. The difference is that the stub does it immediately and the app doesn't want to do it until the end (when it boots a kernel) or not at all, if returning to UEFI. Move it into a function so it can be called as needed. Add a comment showing how to store the memory map so that it can be accessed within the app if needed, for debugging purposes only. The map can change without notice. Signed-off-by: Simon Glass --- include/efi.h | 32 +++++++++++++++++++++ lib/efi/efi.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ lib/efi/efi_app.c | 9 ++++++ lib/efi/efi_stub.c | 66 +++++++----------------------------------- 4 files changed, 124 insertions(+), 55 deletions(-) diff --git a/include/efi.h b/include/efi.h index 877a2e5a8d..dc9907fa16 100644 --- a/include/efi.h +++ b/include/efi.h @@ -407,6 +407,12 @@ static inline struct efi_mem_desc *efi_get_next_mem_desc( * @sys_table: Pointer to system table * @boot: Pointer to boot-services table * @run: Pointer to runtime-services table + * @memmap_key: Key returned from get_memory_map() + * @memmap_desc: List of memory-map records + * @memmap_alloc: Amount of memory allocated for memory map list + * @memmap_size Size of memory-map list in bytes + * @memmap_desc_size: Size of an individual memory-map record, in bytes + * @memmap_version: Memory-map version * * @use_pool_for_malloc: true if all allocation should go through the EFI 'pool' * methods allocate_pool() and free_pool(); false to use 'pages' methods @@ -424,6 +430,12 @@ struct efi_priv { struct efi_system_table *sys_table; struct efi_boot_services *boot; struct efi_runtime_services *run; + efi_uintn_t memmap_key; + struct efi_mem_desc *memmap_desc; + efi_uintn_t memmap_alloc; + efi_uintn_t memmap_size; + efi_uintn_t memmap_desc_size; + u32 memmap_version; /* app: */ bool use_pool_for_malloc; @@ -578,4 +590,24 @@ void efi_putc(struct efi_priv *priv, const char ch); */ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep); +/** + * efi_store_memory_map() - Collect the memory-map info from EFI + * + * Collect the memory info and store it for later use, e.g. in calling + * exit_boot_services() + * + * @priv: Pointer to private EFI structure + * @return 0 if OK, non-zero on error + */ +int efi_store_memory_map(struct efi_priv *priv); + +/** + * efi_call_exit_boot_services() - Handle the exit-boot-service procedure + * + * Tell EFI we don't want their boot services anymore + * + * Return: 0 if OK, non-zero on error + */ +int efi_call_exit_boot_services(void); + #endif /* _LINUX_EFI_H */ diff --git a/lib/efi/efi.c b/lib/efi/efi.c index cd6bf47b18..aa42f1842f 100644 --- a/lib/efi/efi.c +++ b/lib/efi/efi.c @@ -135,3 +135,75 @@ void efi_free(struct efi_priv *priv, void *ptr) boot->free_pool(ptr); } + +int efi_store_memory_map(struct efi_priv *priv) +{ + struct efi_boot_services *boot = priv->sys_table->boottime; + efi_uintn_t size, desc_size; + efi_status_t ret; + + /* Get the memory map so we can switch off EFI */ + size = 0; + ret = boot->get_memory_map(&size, NULL, &priv->memmap_key, + &priv->memmap_desc_size, + &priv->memmap_version); + if (ret != EFI_BUFFER_TOO_SMALL) { + /* + * Note this function avoids using printf() since it is not + * available in the stub + */ + printhex2(EFI_BITS_PER_LONG); + putc(' '); + printhex2(ret); + puts(" No memory map\n"); + return ret; + } + /* + * Since doing a malloc() may change the memory map and also we want to + * be able to read the memory map in efi_call_exit_boot_services() + * below, after more changes have happened + */ + priv->memmap_alloc = size + 1024; + priv->memmap_size = priv->memmap_alloc; + priv->memmap_desc = efi_malloc(priv, size, &ret); + if (!priv->memmap_desc) { + printhex2(ret); + puts(" No memory for memory descriptor\n"); + return ret; + } + + ret = boot->get_memory_map(&priv->memmap_size, priv->memmap_desc, + &priv->memmap_key, &desc_size, + &priv->memmap_version); + if (ret) { + printhex2(ret); + puts(" Can't get memory map\n"); + return ret; + } + + return 0; +} + +int efi_call_exit_boot_services(void) +{ + struct efi_priv *priv = efi_get_priv(); + const struct efi_boot_services *boot = priv->boot; + efi_uintn_t size; + u32 version; + efi_status_t ret; + + size = priv->memmap_alloc; + ret = boot->get_memory_map(&size, priv->memmap_desc, + &priv->memmap_key, + &priv->memmap_desc_size, &version); + if (ret) { + printhex2(ret); + puts(" Can't get memory map\n"); + return ret; + } + ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key); + if (ret) + return ret; + + return 0; +} diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index d60f2f6c28..5c2593bc4d 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -321,6 +321,15 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; } + /* + * We could store the EFI memory map here, but it changes all the time, + * so this is only useful for debugging. + * + * ret = efi_store_memory_map(priv); + * if (ret) + * return ret; + */ + printf("starting\n"); board_init_f(GD_FLG_SKIP_RELOC); diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c index c89ae7c907..646cde3214 100644 --- a/lib/efi/efi_stub.c +++ b/lib/efi/efi_stub.c @@ -304,15 +304,12 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, { struct efi_priv local_priv, *priv = &local_priv; struct efi_boot_services *boot = sys_table->boottime; - struct efi_mem_desc *desc; struct efi_entry_memmap map; struct efi_gop *gop; struct efi_entry_gopmode mode; struct efi_entry_systable table; efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - efi_uintn_t key, desc_size, size; efi_status_t ret; - u32 version; int cs32; ret = efi_init(priv, "Payload", image, sys_table); @@ -327,24 +324,11 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, if (cs32 < 0) return EFI_UNSUPPORTED; - /* Get the memory map so we can switch off EFI */ - size = 0; - ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version); - if (ret != EFI_BUFFER_TOO_SMALL) { - printhex2(EFI_BITS_PER_LONG); - putc(' '); - printhex2(ret); - puts(" No memory map\n"); + ret = efi_store_memory_map(priv); + if (ret) return ret; - } - size += 1024; /* Since doing a malloc() may change the memory map! */ - desc = efi_malloc(priv, size, &ret); - if (!desc) { - printhex2(ret); - puts(" No memory for memory descriptor\n"); - return ret; - } - ret = setup_info_table(priv, size + 128); + + ret = setup_info_table(priv, priv->memmap_size + 128); if (ret) return ret; @@ -360,48 +344,20 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, sizeof(struct efi_gop_mode_info)); } - ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version); - if (ret) { - printhex2(ret); - puts(" Can't get memory map\n"); - return ret; - } - table.sys_table = (ulong)sys_table; add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); - ret = boot->exit_boot_services(image, key); - if (ret) { - /* - * Unfortunately it happens that we cannot exit boot services - * the first time. But the second time it work. I don't know - * why but this seems to be a repeatable problem. To get - * around it, just try again. - */ - printhex2(ret); - puts(" Can't exit boot services\n"); - size = sizeof(desc); - ret = boot->get_memory_map(&size, desc, &key, &desc_size, - &version); - if (ret) { - printhex2(ret); - puts(" Can't get memory map\n"); - return ret; - } - ret = boot->exit_boot_services(image, key); - if (ret) { - printhex2(ret); - puts(" Can't exit boot services 2\n"); - return ret; - } - } + ret = efi_call_exit_boot_services(); + if (ret) + return ret; /* The EFI UART won't work now, switch to a debug one */ use_uart = true; - map.version = version; - map.desc_size = desc_size; - add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size); + map.version = priv->memmap_version; + map.desc_size = priv->memmap_desc_size; + add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), + priv->memmap_desc, priv->memmap_size); add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0); memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_bin_start, From ce1dc0cc17e94a0bf1c17bd1465cb0afd5bfb214 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:11 -0700 Subject: [PATCH 21/28] x86: efi: Update efi_get_next_mem_desc() to avoid needing a map At present this function requires a pointer to struct efi_entry_memmap but the only field used in there is the desc_size. We want to be able to use it from the app, so update it to use desc_size directly. Signed-off-by: Simon Glass --- arch/x86/cpu/efi/payload.c | 8 ++++---- cmd/efi.c | 34 ++++++++++++++++++---------------- include/efi.h | 4 ++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index 04ce1880b4..b7778565b1 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -51,7 +51,7 @@ ulong board_get_usable_ram_top(ulong total_size) end = (struct efi_mem_desc *)((ulong)map + size); desc = map->desc; - for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + for (; desc < end; desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->type != EFI_CONVENTIONAL_MEMORY || desc->physical_start >= 1ULL << 32) continue; @@ -89,7 +89,7 @@ int dram_init(void) end = (struct efi_mem_desc *)((ulong)map + size); gd->ram_size = 0; desc = map->desc; - for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + for (; desc < end; desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->type < EFI_MMAP_IO) gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT; } @@ -114,7 +114,7 @@ int dram_init_banksize(void) desc = map->desc; for (num_banks = 0; desc < end && num_banks < CONFIG_NR_DRAM_BANKS; - desc = efi_get_next_mem_desc(map, desc)) { + desc = efi_get_next_mem_desc(desc, map->desc_size)) { /* * We only use conventional memory and ignore * anything less than 1MB. @@ -197,7 +197,7 @@ unsigned int install_e820_map(unsigned int max_entries, end = (struct efi_mem_desc *)((ulong)map + size); for (desc = map->desc; desc < end; - desc = efi_get_next_mem_desc(map, desc)) { + desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->num_pages == 0) continue; diff --git a/cmd/efi.c b/cmd/efi.c index f2ed26bd4b..d2400acbbb 100644 --- a/cmd/efi.c +++ b/cmd/efi.c @@ -75,16 +75,17 @@ static int h_cmp_entry(const void *v1, const void *v2) /** * efi_build_mem_table() - make a sorted copy of the memory table * - * @map: Pointer to EFI memory map table + * @desc_base: Pointer to EFI memory map table * @size: Size of table in bytes + * @desc_size: Size of each @desc_base record * @skip_bs: True to skip boot-time memory and merge it with conventional * memory. This will significantly reduce the number of table * entries. * Return: pointer to the new table. It should be freed with free() by the * caller. */ -static void *efi_build_mem_table(struct efi_entry_memmap *map, int size, - bool skip_bs) +static void *efi_build_mem_table(struct efi_mem_desc *desc_base, int size, + int desc_size, bool skip_bs) { struct efi_mem_desc *desc, *end, *base, *dest, *prev; int count; @@ -95,15 +96,16 @@ static void *efi_build_mem_table(struct efi_entry_memmap *map, int size, debug("%s: Cannot allocate %#x bytes\n", __func__, size); return NULL; } - end = (struct efi_mem_desc *)((ulong)map + size); - count = ((ulong)end - (ulong)map->desc) / map->desc_size; - memcpy(base, map->desc, (ulong)end - (ulong)map->desc); - qsort(base, count, map->desc_size, h_cmp_entry); + end = (void *)desc_base + size; + count = ((ulong)end - (ulong)desc_base) / desc_size; + memcpy(base, desc_base, (ulong)end - (ulong)desc_base); + qsort(base, count, desc_size, h_cmp_entry); prev = NULL; addr = 0; dest = base; - end = (struct efi_mem_desc *)((ulong)base + count * map->desc_size); - for (desc = base; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + end = (struct efi_mem_desc *)((ulong)base + count * desc_size); + for (desc = base; desc < end; + desc = efi_get_next_mem_desc(desc, desc_size)) { bool merge = true; u32 type = desc->type; @@ -116,7 +118,7 @@ static void *efi_build_mem_table(struct efi_entry_memmap *map, int size, if (skip_bs && is_boot_services(desc->type)) type = EFI_CONVENTIONAL_MEMORY; - memcpy(dest, desc, map->desc_size); + memcpy(dest, desc, desc_size); dest->type = type; if (!skip_bs || !prev) merge = false; @@ -131,7 +133,7 @@ static void *efi_build_mem_table(struct efi_entry_memmap *map, int size, prev->num_pages += desc->num_pages; } else { prev = dest; - dest = efi_get_next_mem_desc(map, dest); + dest = efi_get_next_mem_desc(dest, desc_size); } addr = desc->physical_start + (desc->num_pages << EFI_PAGE_SHIFT); @@ -143,8 +145,8 @@ static void *efi_build_mem_table(struct efi_entry_memmap *map, int size, return base; } -static void efi_print_mem_table(struct efi_entry_memmap *map, - struct efi_mem_desc *desc, bool skip_bs) +static void efi_print_mem_table(struct efi_mem_desc *desc, int desc_size, + bool skip_bs) { u64 attr_seen[ATTR_SEEN_MAX]; int attr_seen_count; @@ -158,7 +160,7 @@ static void efi_print_mem_table(struct efi_entry_memmap *map, attr_seen_count = 0; addr = 0; for (upto = 0; desc->type != EFI_MAX_MEMORY_TYPE; - upto++, desc = efi_get_next_mem_desc(map, desc)) { + upto++, desc = efi_get_next_mem_desc(desc, desc_size)) { const char *name; u64 size; @@ -238,13 +240,13 @@ static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, goto done; } - desc = efi_build_mem_table(map, size, skip_bs); + desc = efi_build_mem_table(map->desc, size, map->desc_size, skip_bs); if (!desc) { ret = -ENOMEM; goto done; } - efi_print_mem_table(map, desc, skip_bs); + efi_print_mem_table(desc, map->desc_size, skip_bs); free(desc); done: if (ret) diff --git a/include/efi.h b/include/efi.h index dc9907fa16..3508ff8f63 100644 --- a/include/efi.h +++ b/include/efi.h @@ -395,9 +395,9 @@ struct efi_entry_systable { }; static inline struct efi_mem_desc *efi_get_next_mem_desc( - struct efi_entry_memmap *map, struct efi_mem_desc *desc) + struct efi_mem_desc *desc, int desc_size) { - return (struct efi_mem_desc *)((ulong)desc + map->desc_size); + return (struct efi_mem_desc *)((ulong)desc + desc_size); } /** From 25a326b0066b3c449a0a91889b0ce19cb7320237 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:12 -0700 Subject: [PATCH 22/28] efi: Support the efi command in the app At present the 'efi' command only works in the EFI payload. Update it to work in the app too, so the memory map can be examined. Signed-off-by: Simon Glass Signed-off-by: Heinrich Schuchardt --- cmd/Makefile | 2 +- cmd/efi.c | 48 ++++++++++++++++++++++++++++++++--------------- include/efi.h | 15 +++++++++++++++ lib/efi/efi_app.c | 33 ++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/cmd/Makefile b/cmd/Makefile index e31ac15ef7..6623d7eaa0 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_CMD_EXTENSION) += extension_board.o obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o -obj-$(CONFIG_EFI_STUB) += efi.o +obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o obj-$(CONFIG_CMD_ELF) += elf.o obj-$(CONFIG_HUSH_PARSER) += exit.o diff --git a/cmd/efi.c b/cmd/efi.c index d2400acbbb..c0384e0db2 100644 --- a/cmd/efi.c +++ b/cmd/efi.c @@ -13,6 +13,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + static const char *const type_name[] = { "reserved", "loader_code", @@ -217,37 +219,53 @@ static void efi_print_mem_table(struct efi_mem_desc *desc, int desc_size, static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - struct efi_mem_desc *desc; - struct efi_entry_memmap *map; + struct efi_mem_desc *orig, *desc; + uint version, key; + int desc_size; int size, ret; bool skip_bs; skip_bs = !argc || *argv[0] != 'a'; - ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); - switch (ret) { - case -ENOENT: - printf("No EFI table available\n"); - goto done; - case -EPROTONOSUPPORT: - printf("Incorrect EFI table version\n"); - goto done; + if (IS_ENABLED(CONFIG_EFI_APP)) { + ret = efi_get_mmap(&orig, &size, &key, &desc_size, &version); + if (ret) { + printf("Cannot read memory map (err=%d)\n", ret); + return CMD_RET_FAILURE; + } + } else { + struct efi_entry_memmap *map; + + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); + switch (ret) { + case -ENOENT: + printf("No EFI table available\n"); + goto done; + case -EPROTONOSUPPORT: + printf("Incorrect EFI table version\n"); + goto done; + } + orig = map->desc; + desc_size = map->desc_size; + version = map->version; } - printf("EFI table at %lx, memory map %p, size %x, version %x, descr. size %#x\n", - gd->arch.table, map, size, map->version, map->desc_size); - if (map->version != EFI_MEM_DESC_VERSION) { + printf("EFI table at %lx, memory map %p, size %x, key %x, version %x, descr. size %#x\n", + gd->arch.table, orig, size, key, version, desc_size); + if (version != EFI_MEM_DESC_VERSION) { printf("Incorrect memory map version\n"); ret = -EPROTONOSUPPORT; goto done; } - desc = efi_build_mem_table(map->desc, size, map->desc_size, skip_bs); + desc = efi_build_mem_table(orig, size, desc_size, skip_bs); if (!desc) { ret = -ENOMEM; goto done; } - efi_print_mem_table(desc, map->desc_size, skip_bs); + efi_print_mem_table(desc, desc_size, skip_bs); free(desc); + if (IS_ENABLED(CONFIG_EFI_APP)) + free(orig); done: if (ret) printf("Error: %d\n", ret); diff --git a/include/efi.h b/include/efi.h index 3508ff8f63..9b7ba0d54d 100644 --- a/include/efi.h +++ b/include/efi.h @@ -610,4 +610,19 @@ int efi_store_memory_map(struct efi_priv *priv); */ int efi_call_exit_boot_services(void); +/** + * efi_get_mmap() - Get the memory map from EFI + * + * This is used in the app. The caller must free *@descp when done + * + * @descp: Returns allocated pointer to EFI memory map table + * @sizep: Returns size of table in bytes + * @keyp: Returns memory-map key + * @desc_sizep: Returns size of each @desc_base record + * @versionp: Returns version number of memory map + * @return 0 on success, -ve on error + */ +int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp, + int *desc_sizep, uint *versionp); + #endif /* _LINUX_EFI_H */ diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index 5c2593bc4d..6980933d7e 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -32,6 +32,39 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep) return -ENOSYS; } +int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp, + int *desc_sizep, uint *versionp) +{ + struct efi_priv *priv = efi_get_priv(); + struct efi_boot_services *boot = priv->sys_table->boottime; + efi_uintn_t size, desc_size, key; + struct efi_mem_desc *desc; + efi_status_t ret; + u32 version; + + /* Get the memory map so we can switch off EFI */ + size = 0; + ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version); + if (ret != EFI_BUFFER_TOO_SMALL) + return log_msg_ret("get", -ENOMEM); + + desc = malloc(size); + if (!desc) + return log_msg_ret("mem", -ENOMEM); + + ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version); + if (ret) + return log_msg_ret("get", -EINVAL); + + *descp = desc; + *sizep = size; + *desc_sizep = desc_size; + *versionp = version; + *keyp = key; + + return 0; +} + /** * efi_bind_block() - bind a new block device to an EFI device * From 450ce56a118975364437cc466ec804d8ded75d29 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:13 -0700 Subject: [PATCH 23/28] x86: efi: Tweak the code used for the 64-bit EFI app Add an empty CPU init function to avoid fiddling with low-level CPU features in the app. Set up the C runtime correctly for 64-bit use and avoid clearing BSS, since this is done by EFI when U-Boot is loaded. Signed-off-by: Simon Glass --- arch/x86/cpu/x86_64/cpu.c | 5 +++++ arch/x86/lib/Makefile | 5 ++--- arch/x86/lib/relocate.c | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c index a3674e8e29..6a38761291 100644 --- a/arch/x86/cpu/x86_64/cpu.c +++ b/arch/x86/cpu/x86_64/cpu.c @@ -45,3 +45,8 @@ int cpu_phys_address_size(void) { return CONFIG_CPU_ADDR_BITS; } + +int x86_cpu_init_f(void) +{ + return 0; +} diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 18757b29aa..e5235b7c4f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -65,9 +65,8 @@ endif lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o -ifeq ($(CONFIG_$(SPL_)X86_64),) -obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o -endif +obj-$(CONFIG_EFI_APP_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o +obj-$(CONFIG_EFI_APP_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o ifneq ($(CONFIG_EFI_STUB),) diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c index 6fe5151647..9060d19d46 100644 --- a/arch/x86/lib/relocate.c +++ b/arch/x86/lib/relocate.c @@ -35,6 +35,7 @@ int copy_uboot_to_ram(void) return 0; } +#ifndef CONFIG_EFI_APP int clear_bss(void) { ulong dst_addr = (ulong)&__bss_start + gd->reloc_off; @@ -46,6 +47,7 @@ int clear_bss(void) return 0; } +#endif #if CONFIG_IS_ENABLED(X86_64) static void do_elf_reloc_fixups64(unsigned int text_base, uintptr_t size, From 3b4ae096b0ed21f3646378cb58d4c03ea2404bac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:14 -0700 Subject: [PATCH 24/28] x86: efi: Round out the link script for 64-bit EFI Make sure the linker lists are in the right place and drop the eh_frame section, which is not needed. Signed-off-by: Simon Glass --- arch/x86/lib/elf_x86_64_efi.lds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/lib/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds index b436429b33..75727400aa 100644 --- a/arch/x86/lib/elf_x86_64_efi.lds +++ b/arch/x86/lib/elf_x86_64_efi.lds @@ -63,6 +63,7 @@ SECTIONS *(.rela.data*) *(.rela.got) *(.rela.stab) + *(.rela.u_boot_list*) } . = ALIGN(4096); @@ -70,9 +71,11 @@ SECTIONS . = ALIGN(4096); .dynstr : { *(.dynstr) } . = ALIGN(4096); + + /DISCARD/ : { *(.eh_frame) } + .ignored.reloc : { *(.rela.reloc) - *(.eh_frame) *(.note.GNU-stack) } From 59e8f36dd93e75f406410be97057b22e452741b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:15 -0700 Subject: [PATCH 25/28] x86: efi: Don't use the 64-bit link script for the EFI app That script is not intended for use with EFI, so update the logic to avoid using it. Signed-off-by: Simon Glass Signed-off-by: Christian Melki --- arch/x86/cpu/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/cpu/config.mk b/arch/x86/cpu/config.mk index d3033b4160..87e242a206 100644 --- a/arch/x86/cpu/config.mk +++ b/arch/x86/cpu/config.mk @@ -9,7 +9,7 @@ LDPPFLAGS += -DRESET_VEC_LOC=$(CONFIG_RESET_VEC_LOC) LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16) ifdef CONFIG_X86_64 -ifndef CONFIG_SPL_BUILD +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_EFI_APP),) LDSCRIPT = $(srctree)/arch/x86/cpu/u-boot-64.lds endif endif From 081dfcf783c80a8abf717df984c94970d128b98a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:16 -0700 Subject: [PATCH 26/28] x86: efi: Set the correct link flags for the 64-bit EFI app At present some 32-bit settings are used with the 64-bit app. Fix this by separating out the two cases. Be careful not to break the 64-bit payload, which needs to build a 64-bit EFI stub with a 32-bit U-Boot. Signed-off-by: Christian Melki Signed-off-by: Simon Glass --- arch/x86/config.mk | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 589f2aed2b..889497b6bd 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -20,6 +20,11 @@ IS_32BIT := y endif endif +EFI_IS_32BIT := $(IS_32BIT) +ifdef CONFIG_EFI_STUB_64BIT +EFI_IS_32BIT := +endif + ifeq ($(IS_32BIT),y) PLATFORM_CPPFLAGS += -march=i386 -m32 else @@ -44,8 +49,14 @@ CFLAGS_EFI := -fpic -fshort-wchar # Compiler flags to be removed when building UEFI applications CFLAGS_NON_EFI := -mregparm=3 -fstack-protector-strong -ifeq ($(CONFIG_EFI_STUB_64BIT),) +ifeq ($(IS_32BIT),y) +EFIPAYLOAD_BFDARCH = i386 +else CFLAGS_EFI += $(call cc-option, -mno-red-zone) +EFIPAYLOAD_BFDARCH = x86_64 +endif + +ifeq ($(EFI_IS_32BIT),y) EFIARCH = ia32 EFIPAYLOAD_BFDTARGET = elf32-i386 else @@ -53,8 +64,6 @@ EFIARCH = x86_64 EFIPAYLOAD_BFDTARGET = elf64-x86-64 endif -EFIPAYLOAD_BFDARCH = i386 - LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH) From ce2f09bcc2bdbc7a4b18f5db8a656768c4f98a98 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:17 -0700 Subject: [PATCH 27/28] efi: Build the 64-bit app properly Now that the linker crash is resolved, build the 64-bit EFI app, including all the required code. Signed-off-by: Simon Glass --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0034a844b4..b08bad4873 100644 --- a/Makefile +++ b/Makefile @@ -1781,9 +1781,9 @@ else quiet_cmd_u-boot__ ?= LD $@ cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ -T u-boot.lds $(u-boot-init) \ - $(if $(CONFIG_EFI_APP_64BIT),,--whole-archive) \ + --whole-archive \ $(u-boot-main) \ - $(if $(CONFIG_EFI_APP_64BIT),,--no-whole-archive) \ + --no-whole-archive \ $(PLATFORM_LIBS) -Map u-boot.map; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) endif From 6b3873c5eaf6486db086df51d4cd61a933668f7b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:18 -0700 Subject: [PATCH 28/28] efi: Tidy up some comments in efi header Document the return value in efi_init(). Fix up @sizep in efi_info_get(). Use Return: instead of @return Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- include/efi.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/efi.h b/include/efi.h index 9b7ba0d54d..6159f34ad2 100644 --- a/include/efi.h +++ b/include/efi.h @@ -510,14 +510,14 @@ void efi_set_priv(struct efi_priv *priv); /** * efi_get_sys_table() - Get access to the main EFI system table * - * @return pointer to EFI system table + * Returns: pointer to EFI system table */ struct efi_system_table *efi_get_sys_table(void); /** * efi_get_boot() - Get access to the EFI boot services table * - * @return pointer to EFI boot services table + * Returns: pointer to EFI boot services table */ struct efi_boot_services *efi_get_boot(void); @@ -526,7 +526,7 @@ struct efi_boot_services *efi_get_boot(void); * * This is used when U-Boot is built as an EFI application. * - * @return the base of RAM as known to U-Boot + * Returns: the base of RAM as known to U-Boot */ unsigned long efi_get_ram_base(void); @@ -537,6 +537,7 @@ unsigned long efi_get_ram_base(void); * @banner: Banner to display when starting * @image: The image handle passed to efi_main() * @sys_table: The EFI system table pointer passed to efi_main() + * Return: 0 on succcess, EFI error code on failure */ int efi_init(struct efi_priv *priv, const char *banner, efi_handle_t image, struct efi_system_table *sys_table); @@ -547,7 +548,7 @@ int efi_init(struct efi_priv *priv, const char *banner, efi_handle_t image, * @priv: Pointer to private EFI structure * @size: Number of bytes to allocate * @retp: Return EFI status result - * @return pointer to memory allocated, or NULL on error + * Returns: pointer to memory allocated, or NULL on error */ void *efi_malloc(struct efi_priv *priv, int size, efi_status_t *retp); @@ -584,8 +585,8 @@ void efi_putc(struct efi_priv *priv, const char ch); * * @type: Entry type to search for * @datap: Returns pointer to entry data - * @sizep: Returns pointer to entry size - * @return 0 if OK, -ENODATA if there is no table, -ENOENT if there is no entry + * @sizep: Returns entry size + * Return: 0 if OK, -ENODATA if there is no table, -ENOENT if there is no entry * of the requested type, -EPROTONOSUPPORT if the table has the wrong version */ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep); @@ -597,7 +598,7 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep); * exit_boot_services() * * @priv: Pointer to private EFI structure - * @return 0 if OK, non-zero on error + * Returns: 0 if OK, non-zero on error */ int efi_store_memory_map(struct efi_priv *priv); @@ -620,7 +621,7 @@ int efi_call_exit_boot_services(void); * @keyp: Returns memory-map key * @desc_sizep: Returns size of each @desc_base record * @versionp: Returns version number of memory map - * @return 0 on success, -ve on error + * Returns: 0 on success, -ve on error */ int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp, int *desc_sizep, uint *versionp);