From a426046bcca586d6e9726e8afc4d9ad307cb2877 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 11 Jun 2018 01:06:49 +0200 Subject: [PATCH] Support dual bootloader (#27) * Support dual bootloader Signed-off-by: Pascal Vizeli * Make ova running Signed-off-by: Pascal Vizeli * fix uboot Signed-off-by: Pascal Vizeli * Update supervisor Signed-off-by: Pascal Vizeli * Support all rpi Signed-off-by: Pascal Vizeli --- README.md | 5 +- buildroot-external/barebox-env/boot/system0 | 12 - buildroot-external/barebox-env/boot/system1 | 13 - .../barebox-env/nv/bootchooser.targets | 1 - buildroot-external/board/ova/info | 1 + buildroot-external/board/ova/post-image.sh | 6 +- .../barebox-env/data/barebox-state-rpi.dtbo | Bin 1655 -> 0 bytes .../raspberrypi/barebox-env/init/cmdline | 4 - .../barebox-env/init/rpi_devicetree | 6 - .../board/raspberrypi/barebox.config | 15 - ...rpi-2-re-enable-booting-from-SD-card.patch | 30 - .../0002-Add-HassOS-bootchoiser-state.patch | 167 - ...state-allow-to-overlay-state-backend.patch | 42 - .../board/raspberrypi/post-image.sh | 10 +- buildroot-external/board/raspberrypi/rpi/info | 4 + .../board/raspberrypi/rpi/uboot.config | 2 + .../board/raspberrypi/rpi0-w/info | 4 + .../board/raspberrypi/rpi0-w/uboot.config | 2 + .../board/raspberrypi/rpi2/barebox.config | 1 - .../board/raspberrypi/rpi2/info | 1 + .../board/raspberrypi/rpi2/uboot.config | 2 + .../board/raspberrypi/rpi3-64/info | 4 + .../board/raspberrypi/rpi3-64/uboot.config | 3 + .../board/raspberrypi/rpi3/barebox.config | 1 - .../board/raspberrypi/rpi3/info | 1 + ...YP-mode-handling-and-RasPi-3-support.patch | 295 - ...tch-from-HYP-to-SVC-mode-if-required.patch | 85 - ...onitor-code-to-be-built-without-PSCI.patch | 33 - ...-add-file-for-HYP-mode-related-setup.patch | 192 - ...ure-monitor-when-entered-in-HYP-mode.patch | 25 - ...rnel-in-HYP-mode-when-entered-in-HYP.patch | 26 - ...HYP-vectors-at-PBL-and-Barebox-entry.patch | 84 - ...ion-IDs-for-Pi-3-Model-B-and-Pi-Zero.patch | 38 - .../0010-rpi-add-raspberry-pi-3-support.patch | 136 - .../board/raspberrypi/rpi3/uboot.config | 3 + .../board/raspberrypi/uboot-boot.sh | 51 + .../board/raspberrypi/uboot.config | 27 + .../{ => bootloader}/barebox.config | 2 +- .../barebox}/bin/init | 0 .../bootloader/barebox/boot/system0 | 8 + .../bootloader/barebox/boot/system1 | 8 + .../barebox}/init/bootchooser | 0 .../barebox}/init/cmdline | 0 .../barebox}/init/global_bootargs | 0 .../barebox}/menu/00-boot-auto/action | 0 .../barebox}/menu/00-boot-auto/title | 0 .../barebox/menu/10-boot-A}/action | 0 .../barebox/menu/10-boot-A}/title | 0 .../barebox/menu/20-boot-B}/action | 0 .../barebox/menu/20-boot-B}/title | 0 .../barebox}/menu/30-shell/action | 0 .../barebox}/menu/30-shell/title | 0 .../barebox}/menu/title | 0 .../barebox}/nv/boot.default | 0 .../barebox/nv/bootchooser.A.boot} | 0 .../barebox/nv/bootchooser.B.boot} | 0 .../barebox}/nv/bootchooser.state_prefix | 0 .../bootloader/barebox/nv/bootchooser.targets | 1 + .../barebox}/nv/editcmd | 0 buildroot-external/bootloader/uboot.config | 19 + buildroot-external/configs/ova_defconfig | 7 +- buildroot-external/configs/rpi0_w_defconfig | 92 + buildroot-external/configs/rpi2_defconfig | 26 +- buildroot-external/configs/rpi3_64_defconfig | 92 + buildroot-external/configs/rpi3_defconfig | 92 + buildroot-external/configs/rpi_defconfig | 92 + .../{board/ova => misc}/barebox-state-efi.dtb | Bin 1177 -> 1169 bytes .../misc}/barebox-state-efi.dts | 4 +- buildroot-external/{ca => misc}/dev-ca.pem | 0 buildroot-external/{scripts => misc}/mbr.img | Bin .../{ca => misc}/provisioning-ca.pem | 0 buildroot-external/{ca => misc}/rel-ca.pem | 0 ...dtc-Update-to-upstream-version-1.4.6.patch | 10403 ---------------- ...drivers-of-implement-overlay-support.patch | 1062 -- ...3-drivers-of-bugfix-partition-fixups.patch | 34 - .../0004-command-add-fix_bootargs.patch | 161 - .../rootfs-overlay/etc/fw_env.config | 1 + .../rootfs-overlay/etc/rauc/system.conf | 18 +- .../local-fs.target.wants/mnt-state.mount | 1 + .../rootfs-overlay/mnt/state/.empty | 0 .../usr/lib/systemd/system/mnt-boot.mount | 2 +- .../usr/lib/systemd/system/mnt-data.mount | 2 +- .../usr/lib/systemd/system/mnt-overlay.mount | 2 +- .../usr/lib/systemd/system/mnt-state.mount | 14 + .../usr/lib/systemd/system/rauc-good.timer | 2 +- .../rootfs-overlay/usr/sbin/hassos-expand | 2 +- buildroot-external/scripts/hdd-image.sh | 75 +- buildroot-external/scripts/post-build.sh | 5 +- fdt/barebox-state-efi.dtb | Bin 1177 -> 0 bytes fdt/barebox-state-rpi.dtbo | Bin 1655 -> 0 bytes fdt/barebox-state-rpi.dtso | 85 - misc/hassio-os-partition.png | Bin 18054 -> 0 bytes misc/hassio-os-partition.xml | 1 - scripts/update-dtb.sh | 7 +- 94 files changed, 648 insertions(+), 13004 deletions(-) delete mode 100644 buildroot-external/barebox-env/boot/system0 delete mode 100644 buildroot-external/barebox-env/boot/system1 delete mode 100644 buildroot-external/barebox-env/nv/bootchooser.targets delete mode 100644 buildroot-external/board/raspberrypi/barebox-env/data/barebox-state-rpi.dtbo delete mode 100644 buildroot-external/board/raspberrypi/barebox-env/init/cmdline delete mode 100644 buildroot-external/board/raspberrypi/barebox-env/init/rpi_devicetree delete mode 100644 buildroot-external/board/raspberrypi/barebox.config delete mode 100644 buildroot-external/board/raspberrypi/patches/barebox/0001-ARM-dts-bcm2836-rpi-2-re-enable-booting-from-SD-card.patch delete mode 100644 buildroot-external/board/raspberrypi/patches/barebox/0002-Add-HassOS-bootchoiser-state.patch delete mode 100644 buildroot-external/board/raspberrypi/patches/barebox/0003-common-state-allow-to-overlay-state-backend.patch create mode 100644 buildroot-external/board/raspberrypi/rpi/info create mode 100644 buildroot-external/board/raspberrypi/rpi/uboot.config create mode 100644 buildroot-external/board/raspberrypi/rpi0-w/info create mode 100644 buildroot-external/board/raspberrypi/rpi0-w/uboot.config delete mode 100644 buildroot-external/board/raspberrypi/rpi2/barebox.config create mode 100644 buildroot-external/board/raspberrypi/rpi2/uboot.config create mode 100644 buildroot-external/board/raspberrypi/rpi3-64/info create mode 100644 buildroot-external/board/raspberrypi/rpi3-64/uboot.config delete mode 100644 buildroot-external/board/raspberrypi/rpi3/barebox.config delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0001-HYP-mode-handling-and-RasPi-3-support.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0002-safely-switch-from-HYP-to-SVC-mode-if-required.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0003-allow-secure-monitor-code-to-be-built-without-PSCI.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0004-add-file-for-HYP-mode-related-setup.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0005-dont-try-to-install-secure-monitor-when-entered-in-HYP-mode.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0006-default-to-starting-kernel-in-HYP-mode-when-entered-in-HYP.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0007-install-HYP-vectors-at-PBL-and-Barebox-entry.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0009-add-revision-IDs-for-Pi-3-Model-B-and-Pi-Zero.patch delete mode 100644 buildroot-external/board/raspberrypi/rpi3/patches/barebox/0010-rpi-add-raspberry-pi-3-support.patch create mode 100644 buildroot-external/board/raspberrypi/rpi3/uboot.config create mode 100644 buildroot-external/board/raspberrypi/uboot-boot.sh create mode 100644 buildroot-external/board/raspberrypi/uboot.config rename buildroot-external/{ => bootloader}/barebox.config (97%) rename buildroot-external/{barebox-env => bootloader/barebox}/bin/init (100%) create mode 100644 buildroot-external/bootloader/barebox/boot/system0 create mode 100644 buildroot-external/bootloader/barebox/boot/system1 rename buildroot-external/{barebox-env => bootloader/barebox}/init/bootchooser (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/init/cmdline (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/init/global_bootargs (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/menu/00-boot-auto/action (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/menu/00-boot-auto/title (100%) rename buildroot-external/{barebox-env/menu/10-boot-system0 => bootloader/barebox/menu/10-boot-A}/action (100%) rename buildroot-external/{barebox-env/menu/10-boot-system0 => bootloader/barebox/menu/10-boot-A}/title (100%) rename buildroot-external/{barebox-env/menu/20-boot-system1 => bootloader/barebox/menu/20-boot-B}/action (100%) rename buildroot-external/{barebox-env/menu/20-boot-system1 => bootloader/barebox/menu/20-boot-B}/title (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/menu/30-shell/action (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/menu/30-shell/title (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/menu/title (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/nv/boot.default (100%) rename buildroot-external/{barebox-env/nv/bootchooser.system0.boot => bootloader/barebox/nv/bootchooser.A.boot} (100%) rename buildroot-external/{barebox-env/nv/bootchooser.system1.boot => bootloader/barebox/nv/bootchooser.B.boot} (100%) rename buildroot-external/{barebox-env => bootloader/barebox}/nv/bootchooser.state_prefix (100%) create mode 100644 buildroot-external/bootloader/barebox/nv/bootchooser.targets rename buildroot-external/{barebox-env => bootloader/barebox}/nv/editcmd (100%) create mode 100644 buildroot-external/bootloader/uboot.config create mode 100644 buildroot-external/configs/rpi0_w_defconfig create mode 100644 buildroot-external/configs/rpi3_64_defconfig create mode 100644 buildroot-external/configs/rpi3_defconfig create mode 100644 buildroot-external/configs/rpi_defconfig rename buildroot-external/{board/ova => misc}/barebox-state-efi.dtb (55%) rename {fdt => buildroot-external/misc}/barebox-state-efi.dts (97%) rename buildroot-external/{ca => misc}/dev-ca.pem (100%) rename buildroot-external/{scripts => misc}/mbr.img (100%) rename buildroot-external/{ca => misc}/provisioning-ca.pem (100%) rename buildroot-external/{ca => misc}/rel-ca.pem (100%) delete mode 100644 buildroot-external/patches/barebox/0001-scripts-dtc-Update-to-upstream-version-1.4.6.patch delete mode 100644 buildroot-external/patches/barebox/0002-drivers-of-implement-overlay-support.patch delete mode 100644 buildroot-external/patches/barebox/0003-drivers-of-bugfix-partition-fixups.patch delete mode 100644 buildroot-external/patches/barebox/0004-command-add-fix_bootargs.patch create mode 100644 buildroot-external/rootfs-overlay/etc/fw_env.config create mode 120000 buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/mnt-state.mount create mode 100644 buildroot-external/rootfs-overlay/mnt/state/.empty create mode 100644 buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount delete mode 100644 fdt/barebox-state-efi.dtb delete mode 100644 fdt/barebox-state-rpi.dtbo delete mode 100644 fdt/barebox-state-rpi.dtso delete mode 100644 misc/hassio-os-partition.png delete mode 100644 misc/hassio-os-partition.xml diff --git a/README.md b/README.md index d20df8d87..9073eb16b 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,11 @@ Hass.io OS based on [buildroot](https://buildroot.org/). It's a hypervisor for D ## Focus - Linux kernel 4.14 (LT) -- Barebox as bootloader +- Barebox as bootloader on EFI +- U-Boot as bootloader on IoT - RAUC for OTA updates - SquashFS LZ4 as filesystem -- Docker 17.12.1 +- Docker 18.03.1 - AppArmor protected - ZRAM LZ4 for /tmp, /var, swap - Run every supervisor diff --git a/buildroot-external/barebox-env/boot/system0 b/buildroot-external/barebox-env/boot/system0 deleted file mode 100644 index 7f2564386..000000000 --- a/buildroot-external/barebox-env/boot/system0 +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -global linux.bootargs.dyn.root="root=PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd rootfstype=squashfs ro" - -mkdir -p /mnt/system -mount -t squashfs /dev/disk0.hassos-system0 /mnt/system - -if [ -f "/mnt/system/boot/bzImage" ]; then - global bootm.image="/mnt/system/boot/bzImage" -else - global bootm.image="/mnt/system/boot/zImage" -fi diff --git a/buildroot-external/barebox-env/boot/system1 b/buildroot-external/barebox-env/boot/system1 deleted file mode 100644 index 5d6fd6650..000000000 --- a/buildroot-external/barebox-env/boot/system1 +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -global linux.bootargs.dyn.root="root=PARTUUID=a3ec664e-32ce-4665-95ea-7ae90ce9aa20 rootfstype=squashfs ro" - -mkdir -p /mnt/system -mount -t squashfs /dev/disk0.hassos-system1 /mnt/system - -if [ -f "/mnt/system/boot/bzImage" ]; then - global bootm.image="/mnt/system/boot/bzImage" -else - global bootm.image="/mnt/system/boot/zImage" -fi - diff --git a/buildroot-external/barebox-env/nv/bootchooser.targets b/buildroot-external/barebox-env/nv/bootchooser.targets deleted file mode 100644 index f0fb14eea..000000000 --- a/buildroot-external/barebox-env/nv/bootchooser.targets +++ /dev/null @@ -1 +0,0 @@ -system0 system1 diff --git a/buildroot-external/board/ova/info b/buildroot-external/board/ova/info index 4d22261e2..2ce3bc85c 100644 --- a/buildroot-external/board/ova/info +++ b/buildroot-external/board/ova/info @@ -1,3 +1,4 @@ BOARD_ID=ova BOARD_NAME="Open Virtual Appliance" CHASSIS=vm +BOOTLOADER=barebox diff --git a/buildroot-external/board/ova/post-image.sh b/buildroot-external/board/ova/post-image.sh index 32099a65e..d115a22e4 100755 --- a/buildroot-external/board/ova/post-image.sh +++ b/buildroot-external/board/ova/post-image.sh @@ -18,13 +18,15 @@ mkdir -p ${BOOT_DATA}/EFI/BOOT mkdir -p ${BOOT_DATA}/EFI/barebox cp ${BINARIES_DIR}/barebox.bin ${BOOT_DATA}/EFI/BOOT/BOOTx64.EFI -cp ${BOARD_DIR}/barebox-state-efi.dtb ${BOOT_DATA}/EFI/barebox/state.dtb +cp ${BR2_EXTERNAL_HASSOS_PATH}/misc/barebox-state-efi.dtb ${BOOT_DATA}/EFI/barebox/state.dtb -echo "console=tty1" > ${BOOT_DIR}/cmdline.txt +echo "console=tty1" > ${BOOT_DATA}/cmdline.txt # Create other layers create_boot_image ${BINARIES_DIR} create_overlay_image ${BINARIES_DIR} +create_kernel_image ${BINARIES_DIR} bzImage +create_barebox_state_image ${BINARIES_DIR} create_disk_image ${BINARIES_DIR} ${BINARIES_DIR}/harddisk.img 6 diff --git a/buildroot-external/board/raspberrypi/barebox-env/data/barebox-state-rpi.dtbo b/buildroot-external/board/raspberrypi/barebox-env/data/barebox-state-rpi.dtbo deleted file mode 100644 index e8eefc5b7e657664d034ad80a93da4fc4cbbbf0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1655 zcmbVMy^_-~5SD>EIQ|Y8C}=34fZ{UF&jBF?WGLwZA?$@`s zZ$KlL+aM&SipBEeU=7xL`0eU~u^$x0Hn6d1XN2sZw`|M{`3A9+W)0pZZhx?7&#Z1NAmMFtD3bf=iv8Zi2lH)^+e}auQUVC|O9& z^69|$zT=0Tz6sM|w6*W|5kyw}_COznRB)~ zfbZAPKPX`fFZ8$EPrKLK*6oqqufZ5}Fg%T_?ok9U$g-#@*!Tw!f7aqKF;vZ&nN(G* z&nt?AOsMEaL;ikSK)G0tb?*S)T^z11ZM~Pste}R+f{}^_!3>s~JfUf-nAW|72?3_& zpIJQ@G-iS*HYde`=4lfO&!kz9jLvxiZ%J~@^3>^`DGSyZ+9;kfL?kJj(WNkU*Tx~L Ls;E=wFGKzUx1kN# diff --git a/buildroot-external/board/raspberrypi/barebox-env/init/cmdline b/buildroot-external/board/raspberrypi/barebox-env/init/cmdline deleted file mode 100644 index 7e9eb2947..000000000 --- a/buildroot-external/board/raspberrypi/barebox-env/init/cmdline +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# Ignore cmdline.txt on raspberry pi -global linux.bootargs.base="" diff --git a/buildroot-external/board/raspberrypi/barebox-env/init/rpi_devicetree b/buildroot-external/board/raspberrypi/barebox-env/init/rpi_devicetree deleted file mode 100644 index 3359638cc..000000000 --- a/buildroot-external/board/raspberrypi/barebox-env/init/rpi_devicetree +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -memcpy -d /tmp/rpi.dtb 0x02008000 0 0x8000 -oftree -f -l /tmp/rpi.dtb -of_overlay /env/data/barebox-state-rpi.dtbo -fix_bootargs diff --git a/buildroot-external/board/raspberrypi/barebox.config b/buildroot-external/board/raspberrypi/barebox.config deleted file mode 100644 index 0768dca83..000000000 --- a/buildroot-external/board/raspberrypi/barebox.config +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_ARCH_BCM283X=y -CONFIG_AEABI=y -CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y -CONFIG_ARM_UNWIND=y -CONFIG_MMU=y -CONFIG_MALLOC_TLSF=y -CONFIG_KALLSYMS=y -CONFIG_IMAGE_COMPRESSION_NONE=y -CONFIG_CMD_OF_OVERLAY=y -CONFIG_CMD_FIX_BOOTARGS=y -# CONFIG_SPI is not set -CONFIG_MCI=y -CONFIG_MCI_BCM283X=y -# CONFIG_PINCTRL is not set -CONFIG_REGULATOR=y diff --git a/buildroot-external/board/raspberrypi/patches/barebox/0001-ARM-dts-bcm2836-rpi-2-re-enable-booting-from-SD-card.patch b/buildroot-external/board/raspberrypi/patches/barebox/0001-ARM-dts-bcm2836-rpi-2-re-enable-booting-from-SD-card.patch deleted file mode 100644 index dc5c9a29a..000000000 --- a/buildroot-external/board/raspberrypi/patches/barebox/0001-ARM-dts-bcm2836-rpi-2-re-enable-booting-from-SD-card.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6344ec5c84a49c2df4c2f26b52d317a34e3bc0c7 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Mon, 4 Jun 2018 07:55:46 +0000 -Subject: [PATCH 1/2] ARM: dts: bcm2836-rpi-2: re-enable booting from SD card - -Signed-off-by: Pascal Vizeli ---- - arch/arm/dts/bcm2836-rpi-2.dts | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/dts/bcm2836-rpi-2.dts b/arch/arm/dts/bcm2836-rpi-2.dts -index 42b6abb18..2fa1c8bb4 100644 ---- a/arch/arm/dts/bcm2836-rpi-2.dts -+++ b/arch/arm/dts/bcm2836-rpi-2.dts -@@ -9,3 +9,12 @@ - reg = <0x0 0x0>; - }; - }; -+ -+&sdhci { -+ status = "okay"; -+}; -+ -+&sdhost { -+ status = "disabled"; -+}; -+ --- -2.17.0 - diff --git a/buildroot-external/board/raspberrypi/patches/barebox/0002-Add-HassOS-bootchoiser-state.patch b/buildroot-external/board/raspberrypi/patches/barebox/0002-Add-HassOS-bootchoiser-state.patch deleted file mode 100644 index 7c57c2dda..000000000 --- a/buildroot-external/board/raspberrypi/patches/barebox/0002-Add-HassOS-bootchoiser-state.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 3fe92c12e01e35cc97fbd92d8ae098ac583cfa1f Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Mon, 4 Jun 2018 09:25:40 +0000 -Subject: [PATCH 3/3] Add HassOS bootchoiser state - -Signed-off-by: Pascal Vizeli ---- - arch/arm/dts/bcm2835-rpi.dts | 69 ++++++++++++++++++++++++++++++++++ - arch/arm/dts/bcm2836-rpi-2.dts | 68 +++++++++++++++++++++++++++++++++ - 2 files changed, 137 insertions(+) - -diff --git a/arch/arm/dts/bcm2835-rpi.dts b/arch/arm/dts/bcm2835-rpi.dts -index 22d60e961..3357d06b7 100644 ---- a/arch/arm/dts/bcm2835-rpi.dts -+++ b/arch/arm/dts/bcm2835-rpi.dts -@@ -13,3 +13,72 @@ - &sdhost { - status = "disabled"; - }; -+ -+/ { -+ -+ aliases { -+ state = &state; -+ }; -+ -+ state: state { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ magic = <0xef98423f>; -+ compatible = "barebox,state"; -+ backend = <&backend_state>; -+ backend-type = "raw"; -+ backend-stridesize = <4048>; -+ -+ bootstate { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ system0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ remaining_attempts@0 { -+ reg = <0x0 0x4>; -+ type = "uint32"; -+ default = <3>; -+ }; -+ priority@4 { -+ reg = <0x4 0x4>; -+ type = "uint32"; -+ default = <20>; -+ }; -+ }; -+ system1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ remaining_attempts@8 { -+ reg = <0x8 0x4>; -+ type = "uint32"; -+ default = <0>; -+ }; -+ priority@c { -+ reg = <0xc 0x4>; -+ type = "uint32"; -+ default = <10>; -+ }; -+ }; -+ last_chosen@10 { -+ reg = <0x10 0x4>; -+ type = "uint32"; -+ }; -+ }; -+ }; -+}; -+ -+&sdhci { -+ partitions { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fixed-partitions"; -+ -+ backend_state: partition@22100000 { -+ label = "state"; -+ reg = <0x22100000 0x800000>; -+ }; -+ }; -+}; -+ -diff --git a/arch/arm/dts/bcm2836-rpi-2.dts b/arch/arm/dts/bcm2836-rpi-2.dts -index bdee1296e..e41def570 100644 ---- a/arch/arm/dts/bcm2836-rpi-2.dts -+++ b/arch/arm/dts/bcm2836-rpi-2.dts -@@ -14,3 +14,71 @@ - status = "disabled"; - }; - -+/ { -+ -+ aliases { -+ state = &state; -+ }; -+ -+ state: state { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ magic = <0xef98423f>; -+ compatible = "barebox,state"; -+ backend = <&backend_state>; -+ backend-type = "raw"; -+ backend-stridesize = <4048>; -+ -+ bootstate { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ system0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ remaining_attempts@0 { -+ reg = <0x0 0x4>; -+ type = "uint32"; -+ default = <3>; -+ }; -+ priority@4 { -+ reg = <0x4 0x4>; -+ type = "uint32"; -+ default = <20>; -+ }; -+ }; -+ system1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ remaining_attempts@8 { -+ reg = <0x8 0x4>; -+ type = "uint32"; -+ default = <0>; -+ }; -+ priority@c { -+ reg = <0xc 0x4>; -+ type = "uint32"; -+ default = <10>; -+ }; -+ }; -+ last_chosen@10 { -+ reg = <0x10 0x4>; -+ type = "uint32"; -+ }; -+ }; -+ }; -+}; -+ -+&sdhci { -+ partitions { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fixed-partitions"; -+ -+ backend_state: partition@22100000 { -+ label = "state"; -+ reg = <0x22100000 0x800000>; -+ }; -+ }; -+}; -+ --- -2.17.0 - diff --git a/buildroot-external/board/raspberrypi/patches/barebox/0003-common-state-allow-to-overlay-state-backend.patch b/buildroot-external/board/raspberrypi/patches/barebox/0003-common-state-allow-to-overlay-state-backend.patch deleted file mode 100644 index 31a2de919..000000000 --- a/buildroot-external/board/raspberrypi/patches/barebox/0003-common-state-allow-to-overlay-state-backend.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 19ab0b433893cc7d16e8f4a6052f0f784131c43a Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Sat, 2 Jun 2018 22:08:31 +0000 -Subject: [PATCH 1/1] common: state: allow to overlay state backend - -This allow to use overlay for state backends. I.e. on raspberry you need -use barebox with SDHCI (slow) and after linux boot it will use SDHOST driver. -But the problem now is, that the state is on SDHCI and dt-utils need it on -SDHOST. Actual it is not possible to overwrite this. - -Signed-off-by: Pascal Vizeli ---- - common/state/state.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/common/state/state.c b/common/state/state.c -index 25d950211..e6259043f 100644 ---- a/common/state/state.c -+++ b/common/state/state.c -@@ -494,8 +494,17 @@ static int of_state_fixup(struct device_node *root, void *ctx) - } - - /* backend phandle */ -- backend_node = of_find_node_by_reproducible_name(root, -- state->backend_reproducible_name); -+ if (node) { -+ ret = of_property_read_u32(node, "backend", &phandle); -+ if (ret) -+ goto out; -+ -+ backend_node = of_find_node_by_phandle_from(phandle, root); -+ } else { -+ backend_node = of_find_node_by_reproducible_name(root, -+ state->backend_reproducible_name); -+ } -+ - if (!backend_node) { - ret = -ENODEV; - goto out; --- -2.17.0 - diff --git a/buildroot-external/board/raspberrypi/post-image.sh b/buildroot-external/board/raspberrypi/post-image.sh index 74db9354c..699d1e2d3 100755 --- a/buildroot-external/board/raspberrypi/post-image.sh +++ b/buildroot-external/board/raspberrypi/post-image.sh @@ -16,7 +16,9 @@ IMAGE_FILE=${BINARIES_DIR}/${HASSOS_ID}_${BOARD_ID}-${VERSION_MAJOR}.${VERSION_B rm -rf ${BOOT_DATA} mkdir -p ${BOOT_DATA} -cp ${BINARIES_DIR}/barebox.bin ${BOOT_DATA}/ +cp -t ${BOOT_DATA} \ + ${BINARIES_DIR}/u-boot.bin \ + ${BINARIES_DIR}/boot.scr cp -t ${BOOT_DATA} \ ${BINARIES_DIR}/*.dtb \ ${BINARIES_DIR}/rpi-firmware/bootcode.bin \ @@ -26,9 +28,7 @@ cp -r ${BINARIES_DIR}/rpi-firmware/overlays ${BOOT_DATA}/ # Update Boot options ( - echo "kernel=barebox.bin" - echo "device_tree_address=0x02008000" - echo "device_tree_end=0x0200ff00" + echo "kernel=u-boot.bin" echo "disable_splash=1" echo "dtparam=audio=on" ) > ${BOOT_DATA}/config.txt @@ -38,6 +38,8 @@ echo "dwc_otg.lpm_enable=0 console=tty1" > ${BOOT_DATA}/cmdline.txt # Create other layers create_boot_image ${BINARIES_DIR} create_overlay_image ${BINARIES_DIR} +create_uboot_state_image ${BINARIES_DIR} +create_kernel_image ${BINARIES_DIR} zImage create_disk_image ${BINARIES_DIR} ${IMAGE_FILE} 2 fix_disk_image_mbr ${IMAGE_FILE} diff --git a/buildroot-external/board/raspberrypi/rpi/info b/buildroot-external/board/raspberrypi/rpi/info new file mode 100644 index 000000000..133129663 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi/info @@ -0,0 +1,4 @@ +BOARD_ID=rpi1 +BOARD_NAME="RaspberryPi" +CHASSIS=embedded +BOOTLOADER=uboot diff --git a/buildroot-external/board/raspberrypi/rpi/uboot.config b/buildroot-external/board/raspberrypi/rpi/uboot.config new file mode 100644 index 000000000..e356b99f4 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi/uboot.config @@ -0,0 +1,2 @@ +CONFIG_TARGET_RPI=y +CONFIG_DEFAULT_DEVICE_TREE="bcm2835-rpi-b" diff --git a/buildroot-external/board/raspberrypi/rpi0-w/info b/buildroot-external/board/raspberrypi/rpi0-w/info new file mode 100644 index 000000000..80244fe15 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi0-w/info @@ -0,0 +1,4 @@ +BOARD_ID=rpi0-w +BOARD_NAME="RaspberryPi Zero-W" +CHASSIS=embedded +BOOTLOADER=uboot diff --git a/buildroot-external/board/raspberrypi/rpi0-w/uboot.config b/buildroot-external/board/raspberrypi/rpi0-w/uboot.config new file mode 100644 index 000000000..03d63bb2e --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi0-w/uboot.config @@ -0,0 +1,2 @@ +CONFIG_TARGET_RPI_0_W=y +CONFIG_DEFAULT_DEVICE_TREE="bcm2835-rpi-zero-w" diff --git a/buildroot-external/board/raspberrypi/rpi2/barebox.config b/buildroot-external/board/raspberrypi/rpi2/barebox.config deleted file mode 100644 index 2806d5f44..000000000 --- a/buildroot-external/board/raspberrypi/rpi2/barebox.config +++ /dev/null @@ -1 +0,0 @@ -CONFIG_MACH_RPI2=y diff --git a/buildroot-external/board/raspberrypi/rpi2/info b/buildroot-external/board/raspberrypi/rpi2/info index 7319f7183..ed3a68dcf 100644 --- a/buildroot-external/board/raspberrypi/rpi2/info +++ b/buildroot-external/board/raspberrypi/rpi2/info @@ -1,3 +1,4 @@ BOARD_ID=rpi2 BOARD_NAME="RaspberryPi 2" CHASSIS=embedded +BOOTLOADER=uboot diff --git a/buildroot-external/board/raspberrypi/rpi2/uboot.config b/buildroot-external/board/raspberrypi/rpi2/uboot.config new file mode 100644 index 000000000..3dfc63491 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi2/uboot.config @@ -0,0 +1,2 @@ +CONFIG_TARGET_RPI_2=y +CONFIG_DEFAULT_DEVICE_TREE="bcm2836-rpi-2-b" diff --git a/buildroot-external/board/raspberrypi/rpi3-64/info b/buildroot-external/board/raspberrypi/rpi3-64/info new file mode 100644 index 000000000..c794e9dba --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi3-64/info @@ -0,0 +1,4 @@ +BOARD_ID=rpi3-64 +BOARD_NAME="RaspberryPi 3 64bit" +CHASSIS=embedded +BOOTLOADER=uboot diff --git a/buildroot-external/board/raspberrypi/rpi3-64/uboot.config b/buildroot-external/board/raspberrypi/rpi3-64/uboot.config new file mode 100644 index 000000000..22cdb3a31 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi3-64/uboot.config @@ -0,0 +1,3 @@ +CONFIG_TARGET_RPI_3=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b" diff --git a/buildroot-external/board/raspberrypi/rpi3/barebox.config b/buildroot-external/board/raspberrypi/rpi3/barebox.config deleted file mode 100644 index 4a8369101..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/barebox.config +++ /dev/null @@ -1 +0,0 @@ -CONFIG_MACH_RPI3=y diff --git a/buildroot-external/board/raspberrypi/rpi3/info b/buildroot-external/board/raspberrypi/rpi3/info index 812dc3619..c6be500c9 100644 --- a/buildroot-external/board/raspberrypi/rpi3/info +++ b/buildroot-external/board/raspberrypi/rpi3/info @@ -1,3 +1,4 @@ BOARD_ID=rpi3 BOARD_NAME="RaspberryPi 3" CHASSIS=embedded +BOOTLOADER=uboot diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0001-HYP-mode-handling-and-RasPi-3-support.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0001-HYP-mode-handling-and-RasPi-3-support.patch deleted file mode 100644 index 6b45b7c81..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0001-HYP-mode-handling-and-RasPi-3-support.patch +++ /dev/null @@ -1,295 +0,0 @@ -Those are needed to generate some of the ARM SEC and VIRT -opcodes in a portable way. - -Signed-off-by: Lucas Stach ---- - arch/arm/include/asm/opcodes-virt.h | 39 ++++++ - arch/arm/include/asm/opcodes.h | 231 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 270 insertions(+) - create mode 100644 arch/arm/include/asm/opcodes-virt.h - create mode 100644 arch/arm/include/asm/opcodes.h - -diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h -new file mode 100644 -index 000000000000..efcfdf92d9d5 ---- /dev/null -+++ b/arch/arm/include/asm/opcodes-virt.h -@@ -0,0 +1,39 @@ -+/* -+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions -+ * Copyright (C) 2012 Linaro Limited -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#ifndef __ASM_ARM_OPCODES_VIRT_H -+#define __ASM_ARM_OPCODES_VIRT_H -+ -+#include -+ -+#define __HVC(imm16) __inst_arm_thumb32( \ -+ 0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F), \ -+ 0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF) \ -+) -+ -+#define __ERET __inst_arm_thumb32( \ -+ 0xE160006E, \ -+ 0xF3DE8F00 \ -+) -+ -+#define __MSR_ELR_HYP(regnum) __inst_arm_thumb32( \ -+ 0xE12EF300 | regnum, \ -+ 0xF3808E30 | (regnum << 16) \ -+) -+ -+#endif /* ! __ASM_ARM_OPCODES_VIRT_H */ -diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h -new file mode 100644 -index 000000000000..a78bf5d2c518 ---- /dev/null -+++ b/arch/arm/include/asm/opcodes.h -@@ -0,0 +1,231 @@ -+/* -+ * arch/arm/include/asm/opcodes.h -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef __ASM_ARM_OPCODES_H -+#define __ASM_ARM_OPCODES_H -+ -+#ifndef __ASSEMBLY__ -+#include -+extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); -+#endif -+ -+#define ARM_OPCODE_CONDTEST_FAIL 0 -+#define ARM_OPCODE_CONDTEST_PASS 1 -+#define ARM_OPCODE_CONDTEST_UNCOND 2 -+ -+ -+/* -+ * Assembler opcode byteswap helpers. -+ * These are only intended for use by this header: don't use them directly, -+ * because they will be suboptimal in most cases. -+ */ -+#define ___asm_opcode_swab32(x) ( \ -+ (((x) << 24) & 0xFF000000) \ -+ | (((x) << 8) & 0x00FF0000) \ -+ | (((x) >> 8) & 0x0000FF00) \ -+ | (((x) >> 24) & 0x000000FF) \ -+) -+#define ___asm_opcode_swab16(x) ( \ -+ (((x) << 8) & 0xFF00) \ -+ | (((x) >> 8) & 0x00FF) \ -+) -+#define ___asm_opcode_swahb32(x) ( \ -+ (((x) << 8) & 0xFF00FF00) \ -+ | (((x) >> 8) & 0x00FF00FF) \ -+) -+#define ___asm_opcode_swahw32(x) ( \ -+ (((x) << 16) & 0xFFFF0000) \ -+ | (((x) >> 16) & 0x0000FFFF) \ -+) -+#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) -+#define ___asm_opcode_identity16(x) ((x) & 0xFFFF) -+ -+ -+/* -+ * Opcode byteswap helpers -+ * -+ * These macros help with converting instructions between a canonical integer -+ * format and in-memory representation, in an endianness-agnostic manner. -+ * -+ * __mem_to_opcode_*() convert from in-memory representation to canonical form. -+ * __opcode_to_mem_*() convert from canonical form to in-memory representation. -+ * -+ * -+ * Canonical instruction representation: -+ * -+ * ARM: 0xKKLLMMNN -+ * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8 -+ * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8 -+ * -+ * There is no way to distinguish an ARM instruction in canonical representation -+ * from a Thumb instruction (just as these cannot be distinguished in memory). -+ * Where this distinction is important, it needs to be tracked separately. -+ * -+ * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not -+ * represent any valid Thumb-2 instruction. For this range, -+ * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. -+ * -+ * The ___asm variants are intended only for use by this header, in situations -+ * involving inline assembler. For .S files, the normal __opcode_*() macros -+ * should do the right thing. -+ */ -+#ifdef __ASSEMBLY__ -+ -+#define ___opcode_swab32(x) ___asm_opcode_swab32(x) -+#define ___opcode_swab16(x) ___asm_opcode_swab16(x) -+#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x) -+#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x) -+#define ___opcode_identity32(x) ___asm_opcode_identity32(x) -+#define ___opcode_identity16(x) ___asm_opcode_identity16(x) -+ -+#else /* ! __ASSEMBLY__ */ -+ -+#include -+#include -+ -+#define ___opcode_swab32(x) swab32(x) -+#define ___opcode_swab16(x) swab16(x) -+#define ___opcode_swahb32(x) swahb32(x) -+#define ___opcode_swahw32(x) swahw32(x) -+#define ___opcode_identity32(x) ((u32)(x)) -+#define ___opcode_identity16(x) ((u16)(x)) -+ -+#endif /* ! __ASSEMBLY__ */ -+ -+ -+#ifdef CONFIG_CPU_ENDIAN_BE8 -+ -+#define __opcode_to_mem_arm(x) ___opcode_swab32(x) -+#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x) -+#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x) -+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x) -+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x) -+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x) -+ -+#else /* ! CONFIG_CPU_ENDIAN_BE8 */ -+ -+#define __opcode_to_mem_arm(x) ___opcode_identity32(x) -+#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x) -+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) -+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x) -+#ifndef CONFIG_CPU_ENDIAN_BE32 -+/* -+ * On BE32 systems, using 32-bit accesses to store Thumb instructions will not -+ * work in all cases, due to alignment constraints. For now, a correct -+ * version is not provided for BE32. -+ */ -+#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x) -+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x) -+#endif -+ -+#endif /* ! CONFIG_CPU_ENDIAN_BE8 */ -+ -+#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) -+#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) -+#ifndef CONFIG_CPU_ENDIAN_BE32 -+#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) -+#endif -+ -+/* Operations specific to Thumb opcodes */ -+ -+/* Instruction size checks: */ -+#define __opcode_is_thumb32(x) ( \ -+ ((x) & 0xF8000000) == 0xE8000000 \ -+ || ((x) & 0xF0000000) == 0xF0000000 \ -+) -+#define __opcode_is_thumb16(x) ( \ -+ ((x) & 0xFFFF0000) == 0 \ -+ && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \ -+) -+ -+/* Operations to construct or split 32-bit Thumb instructions: */ -+#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16)) -+#define __opcode_thumb32_second(x) (___opcode_identity16(x)) -+#define __opcode_thumb32_compose(first, second) ( \ -+ (___opcode_identity32(___opcode_identity16(first)) << 16) \ -+ | ___opcode_identity32(___opcode_identity16(second)) \ -+) -+#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16)) -+#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x)) -+#define ___asm_opcode_thumb32_compose(first, second) ( \ -+ (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \ -+ | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ -+) -+ -+/* -+ * Opcode injection helpers -+ * -+ * In rare cases it is necessary to assemble an opcode which the -+ * assembler does not support directly, or which would normally be -+ * rejected because of the CFLAGS or AFLAGS used to build the affected -+ * file. -+ * -+ * Before using these macros, consider carefully whether it is feasible -+ * instead to change the build flags for your file, or whether it really -+ * makes sense to support old assembler versions when building that -+ * particular kernel feature. -+ * -+ * The macros defined here should only be used where there is no viable -+ * alternative. -+ * -+ * -+ * __inst_arm(x): emit the specified ARM opcode -+ * __inst_thumb16(x): emit the specified 16-bit Thumb opcode -+ * __inst_thumb32(x): emit the specified 32-bit Thumb opcode -+ * -+ * __inst_arm_thumb16(arm, thumb): emit either the specified arm or -+ * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 -+ * kernel is being built -+ * -+ * __inst_arm_thumb32(arm, thumb): emit either the specified arm or -+ * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 -+ * kernel is being built -+ * -+ * -+ * Note that using these macros directly is poor practice. Instead, you -+ * should use them to define human-readable wrapper macros to encode the -+ * instructions that you care about. In code which might run on ARMv7 or -+ * above, you can usually use the __inst_arm_thumb{16,32} macros to -+ * specify the ARM and Thumb alternatives at the same time. This ensures -+ * that the correct opcode gets emitted depending on the instruction set -+ * used for the kernel build. -+ * -+ * Look at opcodes-virt.h for an example of how to use these macros. -+ */ -+#include -+ -+#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) -+#define __inst_thumb32(x) ___inst_thumb32( \ -+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ -+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ -+) -+#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) -+ -+#ifdef CONFIG_THUMB2_BAREBOX -+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ -+ __inst_thumb16(thumb_opcode) -+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ -+ __inst_thumb32(thumb_opcode) -+#else -+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) -+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) -+#endif -+ -+/* Helpers for the helpers. Don't use these directly. */ -+#ifdef __ASSEMBLY__ -+#define ___inst_arm(x) .long x -+#define ___inst_thumb16(x) .short x -+#define ___inst_thumb32(first, second) .short first, second -+#else -+#define ___inst_arm(x) ".long " __stringify(x) "\n\t" -+#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" -+#define ___inst_thumb32(first, second) \ -+ ".short " __stringify(first) ", " __stringify(second) "\n\t" -+#endif -+ -+#endif /* __ASM_ARM_OPCODES_H */ --- -2.16.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0002-safely-switch-from-HYP-to-SVC-mode-if-required.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0002-safely-switch-from-HYP-to-SVC-mode-if-required.patch deleted file mode 100644 index 7218def6a..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0002-safely-switch-from-HYP-to-SVC-mode-if-required.patch +++ /dev/null @@ -1,85 +0,0 @@ -This is a port of the Linux safe_svcmode_maskall macro to -the Barebox lowlevel init. - -Signed-off-by: Lucas Stach ---- - arch/arm/cpu/lowlevel.S | 20 ++++++++++++++++---- - arch/arm/include/asm/system.h | 26 ++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/cpu/lowlevel.S b/arch/arm/cpu/lowlevel.S -index 7696a198e764..194ce0e7c274 100644 ---- a/arch/arm/cpu/lowlevel.S -+++ b/arch/arm/cpu/lowlevel.S -@@ -1,16 +1,28 @@ - #include - #include - #include -+#include - - .section ".text_bare_init_","ax" - ENTRY(arm_cpu_lowlevel_init) - /* save lr, since it may be banked away with a processor mode change */ - mov r2, lr -+ - /* set the cpu to SVC32 mode, mask irq and fiq */ -- mrs r12, cpsr -- bic r12, r12, #0x1f -- orr r12, r12, #0xd3 -- msr cpsr, r12 -+ mrs r12 , cpsr -+ eor r12, r12, #HYP_MODE -+ tst r12, #MODE_MASK -+ bic r12 , r12 , #MODE_MASK -+ orr r12 , r12 , #(PSR_I_BIT | PSR_F_BIT | SVC_MODE) -+THUMB( orr r12 , r12 , #PSR_T_BIT ) -+ bne 1f -+ orr r12, r12, #PSR_A_BIT -+ adr lr, 2f -+ msr spsr_cxsf, r12 -+ __MSR_ELR_HYP(14) -+ __ERET -+1: msr cpsr_c, r12 -+2: - - #if __LINUX_ARM_ARCH__ >= 6 - /* -diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h -index 57c76186b499..55e0f4090295 100644 ---- a/arch/arm/include/asm/system.h -+++ b/arch/arm/include/asm/system.h -@@ -60,6 +60,32 @@ - #define CR_AFE (1 << 29) /* Access flag enable */ - #define CR_TE (1 << 30) /* Thumb exception enable */ - -+/* -+ * PSR bits -+ */ -+#define USR_MODE 0x00000010 -+#define FIQ_MODE 0x00000011 -+#define IRQ_MODE 0x00000012 -+#define SVC_MODE 0x00000013 -+#define ABT_MODE 0x00000017 -+#define HYP_MODE 0x0000001a -+#define UND_MODE 0x0000001b -+#define SYSTEM_MODE 0x0000001f -+#define MODE32_BIT 0x00000010 -+#define MODE_MASK 0x0000001f -+ -+#define PSR_T_BIT 0x00000020 -+#define PSR_F_BIT 0x00000040 -+#define PSR_I_BIT 0x00000080 -+#define PSR_A_BIT 0x00000100 -+#define PSR_E_BIT 0x00000200 -+#define PSR_J_BIT 0x01000000 -+#define PSR_Q_BIT 0x08000000 -+#define PSR_V_BIT 0x10000000 -+#define PSR_C_BIT 0x20000000 -+#define PSR_Z_BIT 0x40000000 -+#define PSR_N_BIT 0x80000000 -+ - #ifndef __ASSEMBLY__ - #if __LINUX_ARM_ARCH__ >= 7 - static inline unsigned int current_el(void) --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0003-allow-secure-monitor-code-to-be-built-without-PSCI.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0003-allow-secure-monitor-code-to-be-built-without-PSCI.patch deleted file mode 100644 index 0517e64aa..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0003-allow-secure-monitor-code-to-be-built-without-PSCI.patch +++ /dev/null @@ -1,33 +0,0 @@ -The hyp mode handling added in the secure monitor code is also useful -when Barebox doesn't have PSCI control. Allow to build without PSCI. - -Signed-off-by: Lucas Stach ---- - arch/arm/cpu/sm_as.S | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/cpu/sm_as.S b/arch/arm/cpu/sm_as.S -index 09580e75de5f..0d01e1bf2435 100644 ---- a/arch/arm/cpu/sm_as.S -+++ b/arch/arm/cpu/sm_as.S -@@ -129,7 +129,9 @@ secure_monitor: - sub sp, sp, #4*4 @ allocate result structure on stack - mov r12, sp - push {r4-r6, r12} -+#ifdef CONFIG_ARM_PSCI - bl psci_entry -+#endif - pop {r4-r6, r12} - ldm r12, {r0-r3} - add sp, sp, #4*4 -@@ -163,6 +165,8 @@ ENTRY(psci_cpu_entry) - mcr p15, 0, r0, c1, c0, 1 @ ACTLR - - bl secure_monitor_stack_setup -+#ifdef CONFIG_ARM_PSCI - bl psci_cpu_entry_c -+#endif - - ENDPROC(psci_cpu_entry) --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0004-add-file-for-HYP-mode-related-setup.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0004-add-file-for-HYP-mode-related-setup.patch deleted file mode 100644 index 19529e6b5..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0004-add-file-for-HYP-mode-related-setup.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 6add848d66a7bdebed73416a3cf27b8bf10a2cd8 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Sat, 19 May 2018 17:58:01 +0200 -Subject: [PATCH 1/1] p2 - ---- - arch/arm/cpu/Makefile | 7 +++ - arch/arm/cpu/hyp.S | 115 ++++++++++++++++++++++++++++++++++++++++++ - arch/arm/cpu/sm_as.S | 11 ---- - arch/arm/include/asm/secure.h | 2 + - 4 files changed, 124 insertions(+), 11 deletions(-) - create mode 100644 arch/arm/cpu/hyp.S - -diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile -index 0316d25..6d67b42 100644 ---- a/arch/arm/cpu/Makefile -+++ b/arch/arm/cpu/Makefile -@@ -9,6 +9,13 @@ obj-y += start.o entry.o - - obj-pbl-y += setupc$(S64).o cache$(S64).o - -+ifeq ($(CONFIG_CPU_64v8),) -+obj-y += hyp.o -+AFLAGS_hyp.o :=-Wa,-march=armv7-a -+pbl-y += hyp.o -+AFLAGS_pbl-hyp.o :=-Wa,-march=armv7-a -+endif -+ - # - # Any variants can be called as start-armxyz.S - # -diff --git a/arch/arm/cpu/hyp.S b/arch/arm/cpu/hyp.S -new file mode 100644 -index 0000000..435d416 ---- /dev/null -+++ b/arch/arm/cpu/hyp.S -@@ -0,0 +1,115 @@ -+#include -+#include -+#include -+ -+.arch_extension sec -+.arch_extension virt -+ -+.section ".text_bare_init_","ax" -+ -+.data -+ .align 2 -+ENTRY(__boot_cpu_mode) -+ .long 0 -+.text -+ -+ENTRY(__hyp_install) -+ mrs r12, cpsr -+ and r12, r12, #MODE_MASK -+ -+ @ Save the initial CPU state -+ adr r0, .L__boot_cpu_mode_offset -+ ldr r1, [r0] -+ str r12, [r0, r1] -+ -+ cmp r12, #HYP_MODE -+ movne pc, lr @ give up if the CPU is not in HYP mode -+ -+ @ Now install the hypervisor stub: -+ adr r12, __hyp_vectors -+ mcr p15, 4, r12, c12, c0, 0 @ set hypervisor vector base (HVBAR) -+ -+ @ Disable all traps, so we don't get any nasty surprise -+ mov r12, #0 -+ mcr p15, 4, r12, c1, c1, 0 @ HCR -+ mcr p15, 4, r12, c1, c1, 2 @ HCPTR -+ mcr p15, 4, r12, c1, c1, 3 @ HSTR -+ -+THUMB( orr r12, #(1 << 30) ) @ HSCTLR.TE -+ mcr p15, 4, r12, c1, c0, 0 @ HSCTLR -+ -+ mrc p15, 4, r12, c1, c1, 1 @ HDCR -+ and r12, #0x1f @ Preserve HPMN -+ mcr p15, 4, r12, c1, c1, 1 @ HDCR -+ -+ @ Make sure NS-SVC is initialised appropriately -+ mrc p15, 0, r12, c1, c0, 0 @ SCTLR -+ orr r12, #(1 << 5) @ CP15 barriers enabled -+ bic r12, #(3 << 7) @ Clear SED/ITD for v8 (RES0 for v7) -+ bic r12, #(3 << 19) @ WXN and UWXN disabled -+ mcr p15, 0, r12, c1, c0, 0 @ SCTLR -+ -+ mrc p15, 0, r12, c0, c0, 0 @ MIDR -+ mcr p15, 4, r12, c0, c0, 0 @ VPIDR -+ -+ mrc p15, 0, r12, c0, c0, 5 @ MPIDR -+ mcr p15, 4, r12, c0, c0, 5 @ VMPIDR -+ bx lr -+ENDPROC(__hyp_install) -+ -+ENTRY(armv7_hyp_install) -+ mov r2, lr -+ -+ bl __hyp_install -+ -+ /* set the cpu to SVC32 mode, mask irq and fiq */ -+ mrs r12 , cpsr -+ eor r12, r12, #HYP_MODE -+ tst r12, #MODE_MASK -+ bic r12 , r12 , #MODE_MASK -+ orr r12 , r12 , #(PSR_I_BIT | PSR_F_BIT | SVC_MODE) -+THUMB( orr r12 , r12 , #PSR_T_BIT ) -+ bne 1f -+ orr r12, r12, #PSR_A_BIT -+ adr lr, 2f -+ msr spsr_cxsf, r12 -+ __MSR_ELR_HYP(14) -+ __ERET -+1: msr cpsr_c, r12 -+2: -+ mov pc, r2 -+ENDPROC(armv7_hyp_install) -+ -+ENTRY(armv7_switch_to_hyp) -+ mov r0, lr -+ mov r1, sp @ save SVC copy of LR and SP -+ isb -+ hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 -+ mov sp, r1 -+ mov lr, r0 @ restore SVC copy of LR and SP -+ -+ bx lr -+ENDPROC(armv7_switch_to_hyp) -+ -+.align 2 -+.L__boot_cpu_mode_offset: -+ .long __boot_cpu_mode - . -+ -+/* The HYP trap is crafted to match armv7_switch_to_hyp() */ -+__hyp_do_trap: -+ mov lr, r0 -+ mov sp, r1 -+ bx lr -+ENDPROC(__hyp_do_trap) -+ -+.align 5 -+__hyp_vectors: -+__hyp_reset: W(b) . -+__hyp_und: W(b) . -+__hyp_svc: W(b) . -+__hyp_pabort: W(b) . -+__hyp_dabort: W(b) . -+__hyp_trap: W(b) __hyp_do_trap -+__hyp_irq: W(b) . -+__hyp_fiq: W(b) . -+ENDPROC(__hyp_vectors) -diff --git a/arch/arm/cpu/sm_as.S b/arch/arm/cpu/sm_as.S -index 0d01e1b..de6cd04 100644 ---- a/arch/arm/cpu/sm_as.S -+++ b/arch/arm/cpu/sm_as.S -@@ -148,17 +148,6 @@ hyp_trap: - mov pc, lr @ do no switch modes, but - @ return to caller - --ENTRY(armv7_switch_to_hyp) -- mov r0, lr -- mov r1, sp @ save SVC copy of LR and SP -- isb -- hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 -- mov sp, r1 -- mov lr, r0 @ restore SVC copy of LR and SP -- -- bx lr --ENDPROC(armv7_switch_to_hyp) -- - ENTRY(psci_cpu_entry) - mrc p15, 0, r0, c1, c0, 1 @ ACTLR - orr r0, r0, #(1 << 6) @ Set SMP bit -diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h -index a4cb1f6..54cc052 100644 ---- a/arch/arm/include/asm/secure.h -+++ b/arch/arm/include/asm/secure.h -@@ -6,8 +6,10 @@ - int armv7_secure_monitor_install(void); - int __armv7_secure_monitor_install(void); - void armv7_switch_to_hyp(void); -+void armv7_hyp_install(void); - - extern unsigned char secure_monitor_init_vectors[]; -+extern int __boot_cpu_mode; - - enum arm_security_state { - ARM_STATE_SECURE, --- -2.7.4 - diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0005-dont-try-to-install-secure-monitor-when-entered-in-HYP-mode.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0005-dont-try-to-install-secure-monitor-when-entered-in-HYP-mode.patch deleted file mode 100644 index 827c9c31e..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0005-dont-try-to-install-secure-monitor-when-entered-in-HYP-mode.patch +++ /dev/null @@ -1,25 +0,0 @@ -When Barebox has been entered in HYP mode, the CPU is already switched -to the non-secure world and it's not possible for Barebox to install -it's own secure monitor. - -Signed-off-by: Lucas Stach ---- - arch/arm/cpu/sm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/cpu/sm.c b/arch/arm/cpu/sm.c -index 5808dfd92bdc..71bb394c8540 100644 ---- a/arch/arm/cpu/sm.c -+++ b/arch/arm/cpu/sm.c -@@ -184,6 +184,9 @@ int armv7_secure_monitor_install(void) - return -EINVAL; - } - -+ if (__boot_cpu_mode == HYP_MODE) -+ return 0; -+ - mmuon = get_cr() & CR_M; - - vbar = get_vbar(); --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0006-default-to-starting-kernel-in-HYP-mode-when-entered-in-HYP.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0006-default-to-starting-kernel-in-HYP-mode-when-entered-in-HYP.patch deleted file mode 100644 index 7119b4c50..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0006-default-to-starting-kernel-in-HYP-mode-when-entered-in-HYP.patch +++ /dev/null @@ -1,26 +0,0 @@ -When Barebox has been entered in HYP mode, there is a high chance that -the kernel is intended to be started in HYP mode also. Get this -default into place. - -Signed-off-by: Lucas Stach ---- - arch/arm/cpu/sm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/cpu/sm.c b/arch/arm/cpu/sm.c -index 71bb394c8540..3369fbb5ff1a 100644 ---- a/arch/arm/cpu/sm.c -+++ b/arch/arm/cpu/sm.c -@@ -264,6 +264,9 @@ static int sm_init(void) - bootm_secure_state_names, - ARRAY_SIZE(bootm_secure_state_names)); - -+ if (__boot_cpu_mode == HYP_MODE) -+ bootm_secure_state = ARM_STATE_HYP; -+ - return 0; - } - device_initcall(sm_init); -\ No newline at end of file --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0007-install-HYP-vectors-at-PBL-and-Barebox-entry.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0007-install-HYP-vectors-at-PBL-and-Barebox-entry.patch deleted file mode 100644 index 03037e419..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0007-install-HYP-vectors-at-PBL-and-Barebox-entry.patch +++ /dev/null @@ -1,84 +0,0 @@ -From f984f8cf4c07f24af7855a4fd69afa3e656238c2 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Sat, 19 May 2018 17:24:42 +0200 -Subject: [PATCH 1/1] p4 - ---- - arch/arm/cpu/lowlevel.S | 3 +++ - arch/arm/cpu/start-pbl.c | 3 +++ - arch/arm/cpu/start.c | 3 +++ - arch/arm/cpu/uncompress.c | 4 ++++ - 4 files changed, 13 insertions(+) - -diff --git a/arch/arm/cpu/lowlevel.S b/arch/arm/cpu/lowlevel.S -index 194ce0e..28ad850 100644 ---- a/arch/arm/cpu/lowlevel.S -+++ b/arch/arm/cpu/lowlevel.S -@@ -8,6 +8,9 @@ ENTRY(arm_cpu_lowlevel_init) - /* save lr, since it may be banked away with a processor mode change */ - mov r2, lr - -+ /* careful: the hyp install corrupts r0 and r1 */ -+ bl __hyp_install -+ - /* set the cpu to SVC32 mode, mask irq and fiq */ - mrs r12 , cpsr - eor r12, r12, #HYP_MODE -diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c -index 16159d7..3f9959e 100644 ---- a/arch/arm/cpu/start-pbl.c -+++ b/arch/arm/cpu/start-pbl.c -@@ -98,5 +98,8 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, - else - barebox = (void *)barebox_base; - -+ if (__boot_cpu_mode == HYP_MODE) -+ armv7_switch_to_hyp(); -+ - barebox(membase, memsize, boarddata); - } -diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c -index 68fff89..1ee13c0 100644 ---- a/arch/arm/cpu/start.c -+++ b/arch/arm/cpu/start.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -145,6 +146,8 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, - unsigned long malloc_start, malloc_end; - unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE; - -+ armv7_hyp_install(); -+ - if (IS_ENABLED(CONFIG_RELOCATABLE)) { - unsigned long barebox_base = arm_mem_barebox_image(membase, - endmem, -diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c -index b07087e..57f324b 100644 ---- a/arch/arm/cpu/uncompress.c -+++ b/arch/arm/cpu/uncompress.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -108,5 +109,8 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, - - pr_debug("jumping to uncompressed image at 0x%p\n", barebox); - -+ if (__boot_cpu_mode == HYP_MODE) -+ armv7_switch_to_hyp(); -+ - barebox(membase, memsize, boarddata); - } --- -2.7.4 - diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0009-add-revision-IDs-for-Pi-3-Model-B-and-Pi-Zero.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0009-add-revision-IDs-for-Pi-3-Model-B-and-Pi-Zero.patch deleted file mode 100644 index ce1a56ecb..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0009-add-revision-IDs-for-Pi-3-Model-B-and-Pi-Zero.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Enrico Joerns - -Signed-off-by: Enrico Joerns ---- - arch/arm/boards/raspberry-pi/rpi-common.c | 2 ++ - arch/arm/mach-bcm283x/include/mach/mbox.h | 4 ++++ - 2 files changed, 6 insertions(+) - -diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c -index 6e375bc984de..aec8cb27ed40 100644 ---- a/arch/arm/boards/raspberry-pi/rpi-common.c -+++ b/arch/arm/boards/raspberry-pi/rpi-common.c -@@ -174,6 +174,8 @@ const struct rpi_model rpi_models_old_scheme[] = { - const struct rpi_model rpi_models_new_scheme[] = { - RPI_MODEL(0, "Unknown model", NULL), - RPI_MODEL(BCM2836_BOARD_REV_2_B, "2 Model B", rpi_b_plus_init), -+ RPI_MODEL(BCM2837_BOARD_REV_3_B, "3 Model B", rpi_b_plus_init), -+ RPI_MODEL(BCM2837_BOARD_REV_ZERO, "Zero", rpi_b_plus_init), - }; - - static int rpi_board_rev = 0; -diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h -index 2b5aea88ee0a..4cddf99a8429 100644 ---- a/arch/arm/mach-bcm283x/include/mach/mbox.h -+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h -@@ -129,6 +129,10 @@ struct bcm2835_mbox_tag_hdr { - - /* RPi 2 */ - #define BCM2836_BOARD_REV_2_B 0x4 -+/* RPi 3 */ -+#define BCM2837_BOARD_REV_3_B 0x8 -+/* Zero */ -+#define BCM2837_BOARD_REV_ZERO 0x9 - - /* - * 0x2..0xf from: --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0010-rpi-add-raspberry-pi-3-support.patch b/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0010-rpi-add-raspberry-pi-3-support.patch deleted file mode 100644 index 2751cc0d0..000000000 --- a/buildroot-external/board/raspberrypi/rpi3/patches/barebox/0010-rpi-add-raspberry-pi-3-support.patch +++ /dev/null @@ -1,136 +0,0 @@ -This adds basic support at the same feature level as the other -supported raspberry pi boards. - -Signed-off-by: Lucas Stach ---- - arch/arm/boards/raspberry-pi/lowlevel.c | 14 ++++++++++++-- - arch/arm/configs/rpi_defconfig | 2 ++ - arch/arm/dts/Makefile | 1 + - arch/arm/dts/bcm2837-rpi-3.dts | 15 +++++++++++++++ - arch/arm/mach-bcm283x/Kconfig | 6 ++++++ - arch/arm/mach-bcm283x/core.c | 1 + - images/Makefile.bcm283x | 4 ++++ - 7 files changed, 41 insertions(+), 2 deletions(-) - create mode 100644 arch/arm/dts/bcm2837-rpi-3.dts - -diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c -index 4e71e29e0c0b..5ca0d3877069 100644 ---- a/arch/arm/boards/raspberry-pi/lowlevel.c -+++ b/arch/arm/boards/raspberry-pi/lowlevel.c -@@ -1,7 +1,7 @@ -+#include -+#include - #include - #include --#include --#include - #include - - extern char __dtb_bcm2835_rpi_start[]; -@@ -23,3 +23,13 @@ ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2) - - barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt); - } -+ -+extern char __dtb_bcm2837_rpi_3_start[]; -+ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2) -+{ -+ void *fdt = __dtb_bcm2837_rpi_3_start - get_runtime_offset(); -+ -+ arm_cpu_lowlevel_init(); -+ -+ barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt); -+} -diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig -index 6dc90c59b36d..34070a05abe7 100644 ---- a/arch/arm/configs/rpi_defconfig -+++ b/arch/arm/configs/rpi_defconfig -@@ -1,9 +1,11 @@ - CONFIG_ARCH_BCM283X=y - CONFIG_MACH_RPI=y - CONFIG_MACH_RPI2=y -+CONFIG_MACH_RPI3=y - CONFIG_AEABI=y - CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y - CONFIG_ARM_UNWIND=y -+CONFIG_IMAGE_COMPRESSION_NONE=y - CONFIG_MMU=y - CONFIG_MALLOC_TLSF=y - CONFIG_KALLSYMS=y -diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile -index 0526a6f40724..0eab313c5011 100644 ---- a/arch/arm/dts/Makefile -+++ b/arch/arm/dts/Makefile -@@ -66,6 +66,7 @@ pbl-dtb-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += rk3288-phycore-som.dtb.o - pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o - pbl-dtb-$(CONFIG_MACH_RPI) += bcm2835-rpi.dtb.o - pbl-dtb-$(CONFIG_MACH_RPI2) += bcm2836-rpi-2.dtb.o -+pbl-dtb-$(CONFIG_MACH_RPI3) += bcm2837-rpi-3.dtb.o - pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o - pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o - pbl-dtb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += imx6sx-sdb.dtb.o -diff --git a/arch/arm/dts/bcm2837-rpi-3.dts b/arch/arm/dts/bcm2837-rpi-3.dts -new file mode 100644 -index 000000000000..f8c58c570137 ---- /dev/null -+++ b/arch/arm/dts/bcm2837-rpi-3.dts -@@ -0,0 +1,15 @@ -+#include -+ -+/ { -+ chosen { -+ stdout-path = &uart0; -+ }; -+ -+ memory { -+ reg = <0x0 0x0>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig -index 1457f114ccaa..af2f88c47acb 100644 ---- a/arch/arm/mach-bcm283x/Kconfig -+++ b/arch/arm/mach-bcm283x/Kconfig -@@ -19,6 +19,12 @@ config MACH_RPI2 - select CPU_V7 - select MACH_RPI_COMMON - -+config MACH_RPI3 -+ bool "RaspberryPi 3 (BCM2837/CORTEX-A53)" -+ select CPU_V7 -+ select MACH_RPI_COMMON -+ select ARM_SECURE_MONITOR -+ - endmenu - - config MACH_RPI_DEBUG_UART_BASE -diff --git a/arch/arm/mach-bcm283x/core.c b/arch/arm/mach-bcm283x/core.c -index fddcb0d1a1d4..26f0996b1cb8 100644 ---- a/arch/arm/mach-bcm283x/core.c -+++ b/arch/arm/mach-bcm283x/core.c -@@ -41,6 +41,7 @@ static int bcm2835_clk_init(void) - clk = clk_fixed("uart0-pl0110", 3 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "uart0-pl0110"); - clk_register_clkdev(clk, NULL, "20201000.serial"); -+ clk_register_clkdev(clk, NULL, "3f201000.serial"); - - clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "bcm2835-cs"); -diff --git a/images/Makefile.bcm283x b/images/Makefile.bcm283x -index d59ef043f05c..d14e648926ac 100644 ---- a/images/Makefile.bcm283x -+++ b/images/Makefile.bcm283x -@@ -9,3 +9,7 @@ image-$(CONFIG_MACH_RPI) += barebox-raspberry-pi-1.img - pblx-$(CONFIG_MACH_RPI2) += start_raspberry_pi2 - FILE_barebox-raspberry-pi-2.img = start_raspberry_pi2.pblx - image-$(CONFIG_MACH_RPI2) += barebox-raspberry-pi-2.img -+ -+pblx-$(CONFIG_MACH_RPI3) += start_raspberry_pi3 -+FILE_barebox-raspberry-pi-3.img = start_raspberry_pi3.pblx -+image-$(CONFIG_MACH_RPI3) += barebox-raspberry-pi-3.img -\ No newline at end of file --- -2.15.1 diff --git a/buildroot-external/board/raspberrypi/rpi3/uboot.config b/buildroot-external/board/raspberrypi/rpi3/uboot.config new file mode 100644 index 000000000..487219591 --- /dev/null +++ b/buildroot-external/board/raspberrypi/rpi3/uboot.config @@ -0,0 +1,3 @@ +CONFIG_TARGET_RPI_3_32B=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b" diff --git a/buildroot-external/board/raspberrypi/uboot-boot.sh b/buildroot-external/board/raspberrypi/uboot-boot.sh new file mode 100644 index 000000000..6a3ed9f81 --- /dev/null +++ b/buildroot-external/board/raspberrypi/uboot-boot.sh @@ -0,0 +1,51 @@ +test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "A B" +test -n "${BOOT_A_LEFT}" || setenv BOOT_A_LEFT 3 +test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3 + +# HassOS bootargs +setenv bootargs_hassos "zram.enabled=1 zram.num_devices=3 apparmor=1 security=apparmor rootwait" + +# HassOS system A/B +setenv bootargs_a "root=PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd rootfstype=squashfs ro" +setenv bootargs_b "root=PARTUUID=a3ec664e-32ce-4665-95ea-7ae90ce9aa20 rootfstype=squashfs ro" + +# Preserve origin bootargs +setenv bootargs_rpi +fdt addr ${fdt_addr} +fdt get value bootargs_rpi /chosen bootargs + +setenv bootargs +for BOOT_SLOT in "${BOOT_ORDER}"; do + if test "x${bootargs}" != "x"; then + # skip remaining slots + elif test "x${BOOT_SLOT}" = "xA"; then + if test ${BOOT_A_LEFT} -gt 0; then + setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1 + echo "Found valid slot A, ${BOOT_A_LEFT} attempts remaining" + setenv load_kernel "ext4load mmc 0:2 ${kernel_addr_r} zImage" + setenv bootargs "${bootargs_hassos} ${bootargs_rpi} ${bootargs_a} rauc.slot=A" + fi + elif test "x${BOOT_SLOT}" = "xB"; then + if test ${BOOT_B_LEFT} -gt 0; then + setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1 + echo "Found valid slot B, ${BOOT_B_LEFT} attempts remaining" + setenv load_kernel "ext4load mmc 0:4 ${kernel_addr_r} zImage" + setenv bootargs "${bootargs_hassos} ${bootargs_rpi} ${bootargs_b} rauc.slot=B" + fi + fi +done + +if test -n "${bootargs}"; then + saveenv +else + echo "No valid slot found, resetting tries to 3" + setenv BOOT_A_LEFT 3 + setenv BOOT_B_LEFT 3 + saveenv + reset +fi + +echo "Loading kernel" +run load_kernel +echo " Starting kernel" +bootz ${kernel_addr_r} - ${fdt_addr} diff --git a/buildroot-external/board/raspberrypi/uboot.config b/buildroot-external/board/raspberrypi/uboot.config new file mode 100644 index 000000000..00cf88bf2 --- /dev/null +++ b/buildroot-external/board/raspberrypi/uboot.config @@ -0,0 +1,27 @@ +CONFIG_ARM=y +CONFIG_ARCH_BCM283X=y +CONFIG_SYS_TEXT_BASE=0x00008000 +CONFIG_OF_BOARD_SETUP=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_OF_EMBED=y +CONFIG_ENV_EXT4_INTERFACE="mmc" +CONFIG_DM_KEYBOARD=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_BCM2835=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_DWC2=y +CONFIG_USB_STORAGE=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_DM_VIDEO=y +CONFIG_PHYS_TO_BUS=y diff --git a/buildroot-external/barebox.config b/buildroot-external/bootloader/barebox.config similarity index 97% rename from buildroot-external/barebox.config rename to buildroot-external/bootloader/barebox.config index 09b149269..1544785f8 100644 --- a/buildroot-external/barebox.config +++ b/buildroot-external/bootloader/barebox.config @@ -43,5 +43,5 @@ CONFIG_DISK_WRITE=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y -CONFIG_FS_SQUASHFS=y +CONFIG_FS_EXT4=y CONFIG_LZ4_DECOMPRESS=y diff --git a/buildroot-external/barebox-env/bin/init b/buildroot-external/bootloader/barebox/bin/init similarity index 100% rename from buildroot-external/barebox-env/bin/init rename to buildroot-external/bootloader/barebox/bin/init diff --git a/buildroot-external/bootloader/barebox/boot/system0 b/buildroot-external/bootloader/barebox/boot/system0 new file mode 100644 index 000000000..bb073c686 --- /dev/null +++ b/buildroot-external/bootloader/barebox/boot/system0 @@ -0,0 +1,8 @@ +#!/bin/sh + +global linux.bootargs.dyn.root="root=PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd rootfstype=squashfs ro" + +mkdir -p /mnt/system +mount -t ext4 /dev/disk0.hassos-kernel0 /mnt/system + +global bootm.image="/mnt/system/bzImage" diff --git a/buildroot-external/bootloader/barebox/boot/system1 b/buildroot-external/bootloader/barebox/boot/system1 new file mode 100644 index 000000000..c60a2c512 --- /dev/null +++ b/buildroot-external/bootloader/barebox/boot/system1 @@ -0,0 +1,8 @@ +#!/bin/sh + +global linux.bootargs.dyn.root="root=PARTUUID=a3ec664e-32ce-4665-95ea-7ae90ce9aa20 rootfstype=squashfs ro" + +mkdir -p /mnt/system +mount -t ext4 /dev/disk0.hassos-kernel1 /mnt/system + +global bootm.image="/mnt/system/bzImage" diff --git a/buildroot-external/barebox-env/init/bootchooser b/buildroot-external/bootloader/barebox/init/bootchooser similarity index 100% rename from buildroot-external/barebox-env/init/bootchooser rename to buildroot-external/bootloader/barebox/init/bootchooser diff --git a/buildroot-external/barebox-env/init/cmdline b/buildroot-external/bootloader/barebox/init/cmdline similarity index 100% rename from buildroot-external/barebox-env/init/cmdline rename to buildroot-external/bootloader/barebox/init/cmdline diff --git a/buildroot-external/barebox-env/init/global_bootargs b/buildroot-external/bootloader/barebox/init/global_bootargs similarity index 100% rename from buildroot-external/barebox-env/init/global_bootargs rename to buildroot-external/bootloader/barebox/init/global_bootargs diff --git a/buildroot-external/barebox-env/menu/00-boot-auto/action b/buildroot-external/bootloader/barebox/menu/00-boot-auto/action similarity index 100% rename from buildroot-external/barebox-env/menu/00-boot-auto/action rename to buildroot-external/bootloader/barebox/menu/00-boot-auto/action diff --git a/buildroot-external/barebox-env/menu/00-boot-auto/title b/buildroot-external/bootloader/barebox/menu/00-boot-auto/title similarity index 100% rename from buildroot-external/barebox-env/menu/00-boot-auto/title rename to buildroot-external/bootloader/barebox/menu/00-boot-auto/title diff --git a/buildroot-external/barebox-env/menu/10-boot-system0/action b/buildroot-external/bootloader/barebox/menu/10-boot-A/action similarity index 100% rename from buildroot-external/barebox-env/menu/10-boot-system0/action rename to buildroot-external/bootloader/barebox/menu/10-boot-A/action diff --git a/buildroot-external/barebox-env/menu/10-boot-system0/title b/buildroot-external/bootloader/barebox/menu/10-boot-A/title similarity index 100% rename from buildroot-external/barebox-env/menu/10-boot-system0/title rename to buildroot-external/bootloader/barebox/menu/10-boot-A/title diff --git a/buildroot-external/barebox-env/menu/20-boot-system1/action b/buildroot-external/bootloader/barebox/menu/20-boot-B/action similarity index 100% rename from buildroot-external/barebox-env/menu/20-boot-system1/action rename to buildroot-external/bootloader/barebox/menu/20-boot-B/action diff --git a/buildroot-external/barebox-env/menu/20-boot-system1/title b/buildroot-external/bootloader/barebox/menu/20-boot-B/title similarity index 100% rename from buildroot-external/barebox-env/menu/20-boot-system1/title rename to buildroot-external/bootloader/barebox/menu/20-boot-B/title diff --git a/buildroot-external/barebox-env/menu/30-shell/action b/buildroot-external/bootloader/barebox/menu/30-shell/action similarity index 100% rename from buildroot-external/barebox-env/menu/30-shell/action rename to buildroot-external/bootloader/barebox/menu/30-shell/action diff --git a/buildroot-external/barebox-env/menu/30-shell/title b/buildroot-external/bootloader/barebox/menu/30-shell/title similarity index 100% rename from buildroot-external/barebox-env/menu/30-shell/title rename to buildroot-external/bootloader/barebox/menu/30-shell/title diff --git a/buildroot-external/barebox-env/menu/title b/buildroot-external/bootloader/barebox/menu/title similarity index 100% rename from buildroot-external/barebox-env/menu/title rename to buildroot-external/bootloader/barebox/menu/title diff --git a/buildroot-external/barebox-env/nv/boot.default b/buildroot-external/bootloader/barebox/nv/boot.default similarity index 100% rename from buildroot-external/barebox-env/nv/boot.default rename to buildroot-external/bootloader/barebox/nv/boot.default diff --git a/buildroot-external/barebox-env/nv/bootchooser.system0.boot b/buildroot-external/bootloader/barebox/nv/bootchooser.A.boot similarity index 100% rename from buildroot-external/barebox-env/nv/bootchooser.system0.boot rename to buildroot-external/bootloader/barebox/nv/bootchooser.A.boot diff --git a/buildroot-external/barebox-env/nv/bootchooser.system1.boot b/buildroot-external/bootloader/barebox/nv/bootchooser.B.boot similarity index 100% rename from buildroot-external/barebox-env/nv/bootchooser.system1.boot rename to buildroot-external/bootloader/barebox/nv/bootchooser.B.boot diff --git a/buildroot-external/barebox-env/nv/bootchooser.state_prefix b/buildroot-external/bootloader/barebox/nv/bootchooser.state_prefix similarity index 100% rename from buildroot-external/barebox-env/nv/bootchooser.state_prefix rename to buildroot-external/bootloader/barebox/nv/bootchooser.state_prefix diff --git a/buildroot-external/bootloader/barebox/nv/bootchooser.targets b/buildroot-external/bootloader/barebox/nv/bootchooser.targets new file mode 100644 index 000000000..5decc2b6a --- /dev/null +++ b/buildroot-external/bootloader/barebox/nv/bootchooser.targets @@ -0,0 +1 @@ +A B diff --git a/buildroot-external/barebox-env/nv/editcmd b/buildroot-external/bootloader/barebox/nv/editcmd similarity index 100% rename from buildroot-external/barebox-env/nv/editcmd rename to buildroot-external/bootloader/barebox/nv/editcmd diff --git a/buildroot-external/bootloader/uboot.config b/buildroot-external/bootloader/uboot.config new file mode 100644 index 000000000..dc8a4158d --- /dev/null +++ b/buildroot-external/bootloader/uboot.config @@ -0,0 +1,19 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_EXPERT is not set +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_SYS_PROMPT="HassOS> " +# CONFIG_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_ENV_IS_NOWHERE is not set +# CONFIG_ENV_IS_IN_FAT is not set +CONFIG_ENV_IS_IN_EXT4=y +CONFIG_ENV_EXT4_DEVICE_AND_PART="0:6" +CONFIG_ENV_EXT4_FILE="/hassos.env" +CONFIG_CONSOLE_SCROLL_LINES=10 +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_REGEX=y +CONFIG_OF_LIBFDT_OVERLAY=y +# CONFIG_EFI_LOADER is not set diff --git a/buildroot-external/configs/ova_defconfig b/buildroot-external/configs/ova_defconfig index a6f6e04bd..c44c5fc42 100644 --- a/buildroot-external/configs/ova_defconfig +++ b/buildroot-external/configs/ova_defconfig @@ -28,7 +28,6 @@ BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y BR2_PACKAGE_JQ=y -BR2_PACKAGE_DOSFSTOOLS=y BR2_PACKAGE_E2FSPROGS=y BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y BR2_PACKAGE_DT_UTILS=y @@ -64,8 +63,8 @@ BR2_TARGET_BAREBOX_CUSTOM_VERSION=y BR2_TARGET_BAREBOX_CUSTOM_VERSION_VALUE="2018.05.0" BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/ova/barebox.config" -BR2_TARGET_BAREBOX_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/barebox.config" -BR2_TARGET_BAREBOX_CUSTOM_EMBEDDED_ENV_PATH="$(BR2_EXTERNAL_HASSOS_PATH)/board/ova/barebox-env $(BR2_EXTERNAL_HASSOS_PATH)/barebox-env" +BR2_TARGET_BAREBOX_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/barebox.config" +BR2_TARGET_BAREBOX_CUSTOM_EMBEDDED_ENV_PATH="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/barebox" BR2_PACKAGE_HOST_DOSFSTOOLS=y BR2_PACKAGE_HOST_E2FSPROGS=y BR2_PACKAGE_HOST_GPTFDISK=y @@ -73,7 +72,7 @@ BR2_PACKAGE_HOST_MTOOLS=y BR2_PACKAGE_HOST_RAUC=y BR2_PACKAGE_HASSOS=y BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/amd64-hassio-supervisor" -BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="105" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/qemux86-64-homeassistant" BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" BR2_PACKAGE_HASSOS_CLI="homeassistant/amd64-hassio-cli" diff --git a/buildroot-external/configs/rpi0_w_defconfig b/buildroot-external/configs/rpi0_w_defconfig new file mode 100644 index 000000000..fca796cb9 --- /dev/null +++ b/buildroot-external/configs/rpi0_w_defconfig @@ -0,0 +1,92 @@ +BR2_arm=y +BR2_arm1176jzf_s=y +BR2_ARM_EABIHF=y +BR2_DL_DIR="/cache/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="/cache/cc" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_14=y +BR2_GCC_VERSION_7_X=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_TARGET_GENERIC_HOSTNAME="hassio" +BR2_TARGET_GENERIC_ISSUE="Welcome to HassOS" +BR2_INIT_SYSTEMD=y +BR2_TARGET_GENERIC_GETTY_PORT="tty1" +# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_HASSOS_PATH)/rootfs-overlay" +BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/post-image.sh" +BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi0-w" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_GIT=y +BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/raspberrypi/linux" +BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="rpi-4.14.y" +BR2_LINUX_KERNEL_DEFCONFIG="bcmrpi" +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="bcm2708-rpi-0-w" +BR2_LINUX_KERNEL_INSTALL_TARGET=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y +BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" +BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y +BR2_PACKAGE_JQ=y +BR2_PACKAGE_E2FSPROGS=y +BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y +BR2_PACKAGE_RPI_WIFI_FIRMWARE=y +BR2_PACKAGE_RPI_FIRMWARE=y +BR2_PACKAGE_GPTFDISK=y +BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_UBOOT_TOOLS=y +BR2_PACKAGE_CA_CERTIFICATES=y +BR2_PACKAGE_LIBDNET=y +BR2_PACKAGE_LIBCGROUP=y +BR2_PACKAGE_LIBCGROUP_TOOLS=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_DROPBEAR=y +# BR2_PACKAGE_DROPBEAR_CLIENT is not set +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +BR2_PACKAGE_NETWORK_MANAGER=y +BR2_PACKAGE_NETWORK_MANAGER_MODEM_MANAGER=y +BR2_PACKAGE_TINI=y +BR2_PACKAGE_DOCKER_ENGINE=y +BR2_PACKAGE_RAUC=y +BR2_PACKAGE_RAUC_NETWORK=y +# BR2_PACKAGE_SYSTEMD_HWDB is not set +# BR2_PACKAGE_SYSTEMD_NETWORKD is not set +BR2_PACKAGE_SYSTEMD_RANDOMSEED=y +# BR2_PACKAGE_SYSTEMD_RESOLVED is not set +BR2_PACKAGE_UTIL_LINUX_PARTX=y +BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y +BR2_TARGET_ROOTFS_SQUASHFS=y +BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y +# BR2_TARGET_ROOTFS_TAR is not set +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2018.05" +BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y +BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi0-w/uboot.config" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/uboot.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot.config" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_TARGET_UBOOT_BOOT_SCRIPT=y +BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot-boot.sh" +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_E2FSPROGS=y +BR2_PACKAGE_HOST_GPTFDISK=y +BR2_PACKAGE_HOST_MTOOLS=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HASSOS=y +BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/armhf-hassio-supervisor" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" +BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi-homeassistant" +BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" +BR2_PACKAGE_HASSOS_CLI="homeassistant/armhf-hassio-cli" +BR2_PACKAGE_HASSOS_CLI_VERSION="3" +BR2_PACKAGE_HASSOS_CLI_PROFILE="docker-default" +BR2_PACKAGE_HASSOS_APPARMOR_DIR="supervisor/apparmor" +BR2_PACKAGE_APPARMOR=y diff --git a/buildroot-external/configs/rpi2_defconfig b/buildroot-external/configs/rpi2_defconfig index 1210d1f98..476193d44 100644 --- a/buildroot-external/configs/rpi2_defconfig +++ b/buildroot-external/configs/rpi2_defconfig @@ -4,7 +4,7 @@ BR2_ARM_FPU_VFPV4=y BR2_DL_DIR="/cache/dl" BR2_CCACHE=y BR2_CCACHE_DIR="/cache/cc" -BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches" BR2_TOOLCHAIN_BUILDROOT_GLIBC=y BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_14=y BR2_GCC_VERSION_7_X=y @@ -33,13 +33,12 @@ BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y BR2_PACKAGE_JQ=y -BR2_PACKAGE_DOSFSTOOLS=y BR2_PACKAGE_E2FSPROGS=y BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y BR2_PACKAGE_RPI_FIRMWARE=y -BR2_PACKAGE_DT_UTILS=y BR2_PACKAGE_GPTFDISK=y BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_UBOOT_TOOLS=y BR2_PACKAGE_CA_CERTIFICATES=y BR2_PACKAGE_LIBDNET=y BR2_PACKAGE_LIBCGROUP=y @@ -65,13 +64,16 @@ BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y BR2_TARGET_ROOTFS_SQUASHFS=y BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y # BR2_TARGET_ROOTFS_TAR is not set -BR2_TARGET_BAREBOX=y -BR2_TARGET_BAREBOX_CUSTOM_VERSION=y -BR2_TARGET_BAREBOX_CUSTOM_VERSION_VALUE="2018.05.0" -BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y -BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/barebox.config" -BR2_TARGET_BAREBOX_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/barebox.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi2/barebox.config" -BR2_TARGET_BAREBOX_CUSTOM_EMBEDDED_ENV_PATH="$(BR2_EXTERNAL_HASSOS_PATH)/barebox-env $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/barebox-env" +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2018.05" +BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y +BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi2/uboot.config" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/uboot.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot.config" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_TARGET_UBOOT_BOOT_SCRIPT=y +BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot-boot.sh" BR2_PACKAGE_HOST_DOSFSTOOLS=y BR2_PACKAGE_HOST_E2FSPROGS=y BR2_PACKAGE_HOST_GPTFDISK=y @@ -79,8 +81,8 @@ BR2_PACKAGE_HOST_MTOOLS=y BR2_PACKAGE_HOST_RAUC=y BR2_PACKAGE_HASSOS=y BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/armhf-hassio-supervisor" -BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="105" -BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi3-homeassistant" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" +BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi2-homeassistant" BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" BR2_PACKAGE_HASSOS_CLI="homeassistant/armhf-hassio-cli" BR2_PACKAGE_HASSOS_CLI_VERSION="3" diff --git a/buildroot-external/configs/rpi3_64_defconfig b/buildroot-external/configs/rpi3_64_defconfig new file mode 100644 index 000000000..7c9d82813 --- /dev/null +++ b/buildroot-external/configs/rpi3_64_defconfig @@ -0,0 +1,92 @@ +BR2_aarch64=y +BR2_cortex_a53=y +BR2_ARM_FPU_VFPV4=y +BR2_DL_DIR="/cache/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="/cache/cc" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_14=y +BR2_GCC_VERSION_7_X=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_TARGET_GENERIC_HOSTNAME="hassio" +BR2_TARGET_GENERIC_ISSUE="Welcome to HassOS" +BR2_INIT_SYSTEMD=y +BR2_TARGET_GENERIC_GETTY_PORT="tty1" +# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_HASSOS_PATH)/rootfs-overlay" +BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/post-image.sh" +BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi3-64" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_GIT=y +BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/raspberrypi/linux" +BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="rpi-4.14.y" +BR2_LINUX_KERNEL_DEFCONFIG="bcmrpi3" +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="bcm2710-rpi-3-b bcm2710-rpi-3-b-plus bcm2710-rpi-cm3" +BR2_LINUX_KERNEL_INSTALL_TARGET=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y +BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" +BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y +BR2_PACKAGE_JQ=y +BR2_PACKAGE_E2FSPROGS=y +BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y +BR2_PACKAGE_RPI_WIFI_FIRMWARE=y +BR2_PACKAGE_RPI_FIRMWARE=y +BR2_PACKAGE_GPTFDISK=y +BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_UBOOT_TOOLS=y +BR2_PACKAGE_CA_CERTIFICATES=y +BR2_PACKAGE_LIBDNET=y +BR2_PACKAGE_LIBCGROUP=y +BR2_PACKAGE_LIBCGROUP_TOOLS=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_DROPBEAR=y +# BR2_PACKAGE_DROPBEAR_CLIENT is not set +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +BR2_PACKAGE_NETWORK_MANAGER=y +BR2_PACKAGE_NETWORK_MANAGER_MODEM_MANAGER=y +BR2_PACKAGE_TINI=y +BR2_PACKAGE_DOCKER_ENGINE=y +BR2_PACKAGE_RAUC=y +BR2_PACKAGE_RAUC_NETWORK=y +# BR2_PACKAGE_SYSTEMD_HWDB is not set +# BR2_PACKAGE_SYSTEMD_NETWORKD is not set +BR2_PACKAGE_SYSTEMD_RANDOMSEED=y +# BR2_PACKAGE_SYSTEMD_RESOLVED is not set +BR2_PACKAGE_UTIL_LINUX_PARTX=y +BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y +BR2_TARGET_ROOTFS_SQUASHFS=y +BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y +# BR2_TARGET_ROOTFS_TAR is not set +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2018.05" +BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y +BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi3-64/uboot.config" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/uboot.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot.config" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_TARGET_UBOOT_BOOT_SCRIPT=y +BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot-boot.sh" +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_E2FSPROGS=y +BR2_PACKAGE_HOST_GPTFDISK=y +BR2_PACKAGE_HOST_MTOOLS=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HASSOS=y +BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/armhf-hassio-supervisor" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" +BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi3-64-homeassistant" +BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" +BR2_PACKAGE_HASSOS_CLI="homeassistant/aarch64-hassio-cli" +BR2_PACKAGE_HASSOS_CLI_VERSION="3" +BR2_PACKAGE_HASSOS_CLI_PROFILE="docker-default" +BR2_PACKAGE_HASSOS_APPARMOR_DIR="supervisor/apparmor" +BR2_PACKAGE_APPARMOR=y diff --git a/buildroot-external/configs/rpi3_defconfig b/buildroot-external/configs/rpi3_defconfig new file mode 100644 index 000000000..998a089d8 --- /dev/null +++ b/buildroot-external/configs/rpi3_defconfig @@ -0,0 +1,92 @@ +BR2_arm=y +BR2_cortex_a53=y +BR2_ARM_FPU_VFPV4=y +BR2_DL_DIR="/cache/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="/cache/cc" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_14=y +BR2_GCC_VERSION_7_X=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_TARGET_GENERIC_HOSTNAME="hassio" +BR2_TARGET_GENERIC_ISSUE="Welcome to HassOS" +BR2_INIT_SYSTEMD=y +BR2_TARGET_GENERIC_GETTY_PORT="tty1" +# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_HASSOS_PATH)/rootfs-overlay" +BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/post-image.sh" +BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi3" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_GIT=y +BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/raspberrypi/linux" +BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="rpi-4.14.y" +BR2_LINUX_KERNEL_DEFCONFIG="bcm2709" +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="bcm2710-rpi-3-b bcm2710-rpi-3-b-plus bcm2710-rpi-cm3" +BR2_LINUX_KERNEL_INSTALL_TARGET=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y +BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" +BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y +BR2_PACKAGE_JQ=y +BR2_PACKAGE_E2FSPROGS=y +BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y +BR2_PACKAGE_RPI_WIFI_FIRMWARE=y +BR2_PACKAGE_RPI_FIRMWARE=y +BR2_PACKAGE_GPTFDISK=y +BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_UBOOT_TOOLS=y +BR2_PACKAGE_CA_CERTIFICATES=y +BR2_PACKAGE_LIBDNET=y +BR2_PACKAGE_LIBCGROUP=y +BR2_PACKAGE_LIBCGROUP_TOOLS=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_DROPBEAR=y +# BR2_PACKAGE_DROPBEAR_CLIENT is not set +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +BR2_PACKAGE_NETWORK_MANAGER=y +BR2_PACKAGE_NETWORK_MANAGER_MODEM_MANAGER=y +BR2_PACKAGE_TINI=y +BR2_PACKAGE_DOCKER_ENGINE=y +BR2_PACKAGE_RAUC=y +BR2_PACKAGE_RAUC_NETWORK=y +# BR2_PACKAGE_SYSTEMD_HWDB is not set +# BR2_PACKAGE_SYSTEMD_NETWORKD is not set +BR2_PACKAGE_SYSTEMD_RANDOMSEED=y +# BR2_PACKAGE_SYSTEMD_RESOLVED is not set +BR2_PACKAGE_UTIL_LINUX_PARTX=y +BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y +BR2_TARGET_ROOTFS_SQUASHFS=y +BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y +# BR2_TARGET_ROOTFS_TAR is not set +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2018.05" +BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y +BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi3/uboot.config" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/uboot.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot.config" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_TARGET_UBOOT_BOOT_SCRIPT=y +BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot-boot.sh" +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_E2FSPROGS=y +BR2_PACKAGE_HOST_GPTFDISK=y +BR2_PACKAGE_HOST_MTOOLS=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HASSOS=y +BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/armhf-hassio-supervisor" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" +BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi3-homeassistant" +BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" +BR2_PACKAGE_HASSOS_CLI="homeassistant/armhf-hassio-cli" +BR2_PACKAGE_HASSOS_CLI_VERSION="3" +BR2_PACKAGE_HASSOS_CLI_PROFILE="docker-default" +BR2_PACKAGE_HASSOS_APPARMOR_DIR="supervisor/apparmor" +BR2_PACKAGE_APPARMOR=y diff --git a/buildroot-external/configs/rpi_defconfig b/buildroot-external/configs/rpi_defconfig new file mode 100644 index 000000000..aebeef528 --- /dev/null +++ b/buildroot-external/configs/rpi_defconfig @@ -0,0 +1,92 @@ +BR2_arm=y +BR2_arm1176jzf_s=y +BR2_ARM_EABIHF=y +BR2_DL_DIR="/cache/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="/cache/cc" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_14=y +BR2_GCC_VERSION_7_X=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_TARGET_GENERIC_HOSTNAME="hassio" +BR2_TARGET_GENERIC_ISSUE="Welcome to HassOS" +BR2_INIT_SYSTEMD=y +BR2_TARGET_GENERIC_GETTY_PORT="tty1" +# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_HASSOS_PATH)/rootfs-overlay" +BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/post-image.sh" +BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_GIT=y +BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/raspberrypi/linux" +BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="rpi-4.14.y" +BR2_LINUX_KERNEL_DEFCONFIG="bcmrpi" +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="bcm2708-rpi-b bcm2708-rpi-b-plus bcm2708-rpi-cm" +BR2_LINUX_KERNEL_INSTALL_TARGET=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y +BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" +BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y +BR2_PACKAGE_JQ=y +BR2_PACKAGE_E2FSPROGS=y +BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y +BR2_PACKAGE_RPI_WIFI_FIRMWARE=y +BR2_PACKAGE_RPI_FIRMWARE=y +BR2_PACKAGE_GPTFDISK=y +BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_UBOOT_TOOLS=y +BR2_PACKAGE_CA_CERTIFICATES=y +BR2_PACKAGE_LIBDNET=y +BR2_PACKAGE_LIBCGROUP=y +BR2_PACKAGE_LIBCGROUP_TOOLS=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_DROPBEAR=y +# BR2_PACKAGE_DROPBEAR_CLIENT is not set +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +BR2_PACKAGE_NETWORK_MANAGER=y +BR2_PACKAGE_NETWORK_MANAGER_MODEM_MANAGER=y +BR2_PACKAGE_TINI=y +BR2_PACKAGE_DOCKER_ENGINE=y +BR2_PACKAGE_RAUC=y +BR2_PACKAGE_RAUC_NETWORK=y +# BR2_PACKAGE_SYSTEMD_HWDB is not set +# BR2_PACKAGE_SYSTEMD_NETWORKD is not set +BR2_PACKAGE_SYSTEMD_RANDOMSEED=y +# BR2_PACKAGE_SYSTEMD_RESOLVED is not set +BR2_PACKAGE_UTIL_LINUX_PARTX=y +BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y +BR2_TARGET_ROOTFS_SQUASHFS=y +BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y +# BR2_TARGET_ROOTFS_TAR is not set +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2018.05" +BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y +BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/rpi/uboot.config" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/bootloader/uboot.config $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot.config" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_TARGET_UBOOT_BOOT_SCRIPT=y +BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/uboot-boot.sh" +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_E2FSPROGS=y +BR2_PACKAGE_HOST_GPTFDISK=y +BR2_PACKAGE_HOST_MTOOLS=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HASSOS=y +BR2_PACKAGE_HASSOS_SUPERVISOR="homeassistant/armhf-hassio-supervisor" +BR2_PACKAGE_HASSOS_SUPERVISOR_VERSION="107" +BR2_PACKAGE_HASSOS_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/raspberrypi-homeassistant" +BR2_PACKAGE_HASSOS_SUPERVISOR_PROFILE="hassio-supervisor" +BR2_PACKAGE_HASSOS_CLI="homeassistant/armhf-hassio-cli" +BR2_PACKAGE_HASSOS_CLI_VERSION="3" +BR2_PACKAGE_HASSOS_CLI_PROFILE="docker-default" +BR2_PACKAGE_HASSOS_APPARMOR_DIR="supervisor/apparmor" +BR2_PACKAGE_APPARMOR=y diff --git a/buildroot-external/board/ova/barebox-state-efi.dtb b/buildroot-external/misc/barebox-state-efi.dtb similarity index 55% rename from buildroot-external/board/ova/barebox-state-efi.dtb rename to buildroot-external/misc/barebox-state-efi.dtb index c4bf99d08649968659d6a8fa427a4c426690c58a..7fcc3137cc276b0b0f2515f1075ef5c6a8d450fb 100644 GIT binary patch delta 53 zcmbQqIgwM~0`I@K3=Aw285kHWfHcoU0ddAF8#Oo>8679)s!i5s5}BOOIF-=}$l0vV Hl*I%9dxQ<{ delta 61 zcmbQpIg?Z10`I@K3=AwY85kHWfV9X&0ddAV8#Oo>*^4WSOHy+UCg!V54rg2m@~J diff --git a/fdt/barebox-state-efi.dts b/buildroot-external/misc/barebox-state-efi.dts similarity index 97% rename from fdt/barebox-state-efi.dts rename to buildroot-external/misc/barebox-state-efi.dts index f337146bf..0b4156527 100644 --- a/fdt/barebox-state-efi.dts +++ b/buildroot-external/misc/barebox-state-efi.dts @@ -18,7 +18,7 @@ #address-cells = <1>; #size-cells = <1>; - system0 { + A { #address-cells = <1>; #size-cells = <1>; remaining_attempts@0 { @@ -32,7 +32,7 @@ default = <20>; }; }; - system1 { + B { #address-cells = <1>; #size-cells = <1>; remaining_attempts@8 { diff --git a/buildroot-external/ca/dev-ca.pem b/buildroot-external/misc/dev-ca.pem similarity index 100% rename from buildroot-external/ca/dev-ca.pem rename to buildroot-external/misc/dev-ca.pem diff --git a/buildroot-external/scripts/mbr.img b/buildroot-external/misc/mbr.img similarity index 100% rename from buildroot-external/scripts/mbr.img rename to buildroot-external/misc/mbr.img diff --git a/buildroot-external/ca/provisioning-ca.pem b/buildroot-external/misc/provisioning-ca.pem similarity index 100% rename from buildroot-external/ca/provisioning-ca.pem rename to buildroot-external/misc/provisioning-ca.pem diff --git a/buildroot-external/ca/rel-ca.pem b/buildroot-external/misc/rel-ca.pem similarity index 100% rename from buildroot-external/ca/rel-ca.pem rename to buildroot-external/misc/rel-ca.pem diff --git a/buildroot-external/patches/barebox/0001-scripts-dtc-Update-to-upstream-version-1.4.6.patch b/buildroot-external/patches/barebox/0001-scripts-dtc-Update-to-upstream-version-1.4.6.patch deleted file mode 100644 index 28371f14a..000000000 --- a/buildroot-external/patches/barebox/0001-scripts-dtc-Update-to-upstream-version-1.4.6.patch +++ /dev/null @@ -1,10403 +0,0 @@ -From 33d62d2531ec28a54acd9392c38e621d2a72472b Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Tue, 5 Jun 2018 22:35:03 +0000 -Subject: [PATCH 1/2] scripts/dtc: Update to upstream version 1.4.6 - -Signed-off-by: Pascal Vizeli ---- - scripts/dtc/.gitignore | 1 - - scripts/dtc/Makefile | 8 +- - scripts/dtc/checks.c | 1194 +++++++++++++++++++++----- - scripts/dtc/data.c | 16 +- - scripts/dtc/dtc-lexer.l | 63 +- - scripts/dtc/dtc-lexer.lex.c_shipped | 894 +++++++++---------- - scripts/dtc/dtc-parser.tab.c_shipped | 813 ++++++++++-------- - scripts/dtc/dtc-parser.tab.h_shipped | 54 +- - scripts/dtc/dtc-parser.y | 91 +- - scripts/dtc/dtc.c | 139 ++- - scripts/dtc/dtc.h | 62 +- - scripts/dtc/fdt.c | 24 +- - scripts/dtc/fdt.h | 6 +- - scripts/dtc/fdt_empty_tree.c | 1 - - scripts/dtc/fdt_overlay.c | 912 ++++++++++++++++++++ - scripts/dtc/fdt_ro.c | 288 ++++++- - scripts/dtc/fdt_rw.c | 121 +-- - scripts/dtc/fdt_strerror.c | 6 + - scripts/dtc/fdt_sw.c | 40 +- - scripts/dtc/fdt_wip.c | 43 +- - scripts/dtc/fdtdump.c | 136 +-- - scripts/dtc/fdtget.c | 60 +- - scripts/dtc/fdtput.c | 142 ++- - scripts/dtc/flattree.c | 105 +-- - scripts/dtc/fstree.c | 5 +- - scripts/dtc/libfdt.h | 429 +++++++-- - scripts/dtc/libfdt_env.h | 60 +- - scripts/dtc/libfdt_internal.h | 32 +- - scripts/dtc/livetree.c | 356 +++++++- - scripts/dtc/srcpos.c | 42 +- - scripts/dtc/srcpos.h | 18 +- - scripts/dtc/treesource.c | 20 +- - scripts/dtc/update-dtc-source.sh | 46 +- - scripts/dtc/util.c | 44 +- - scripts/dtc/util.h | 33 +- - scripts/dtc/version_gen.h | 2 +- - 36 files changed, 4578 insertions(+), 1728 deletions(-) - create mode 100644 scripts/dtc/fdt_overlay.c - -diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore -index 80f6b50fd..cdabdc95a 100644 ---- a/scripts/dtc/.gitignore -+++ b/scripts/dtc/.gitignore -@@ -2,4 +2,3 @@ dtc - dtc-lexer.lex.c - dtc-parser.tab.c - dtc-parser.tab.h --fdtget -diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile -index 05973b12a..06aaa8c55 100644 ---- a/scripts/dtc/Makefile -+++ b/scripts/dtc/Makefile -@@ -1,17 +1,15 @@ - # scripts/dtc makefile - --hostprogs-y := dtc fdtget -+hostprogs-y := dtc - always := $(hostprogs-y) - - dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ - srcpos.o checks.o util.o - dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o - --libfdt-objs = fdt.o fdt_ro.o fdt_strerror.o fdt_wip.o -+libfdt-objs = fdt.o fdt_ro.o fdt_strerror.o fdt_wip.o fdt_overlay.o - libfdt-objs += fdt_empty_tree.o fdt_rw.o fdt_sw.o - --fdtget-objs += fdtget.o $(libfdt-objs) util.o -- - # Source files need to get at the userspace version of libfdt_env.h to compile - - HOSTCFLAGS_DTC := -I$(src) -@@ -33,7 +31,7 @@ HOSTCFLAGS_fdt_wip.o := $(HOSTCFLAGS_DTC) - HOSTCFLAGS_fdt_empty_tree.o := $(HOSTCFLAGS_DTC) - HOSTCFLAGS_fdt_rw.o := $(HOSTCFLAGS_DTC) - HOSTCFLAGS_fdt_sw.o := $(HOSTCFLAGS_DTC) --HOSTCFLAGS_fdtget.o := $(HOSTCFLAGS_DTC) -+HOSTCFLAGS_fdt_overlay.o := $(HOSTCFLAGS_DTC) - - HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC) - HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 3bf0fa4a4..815eaf140 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -40,16 +40,11 @@ enum checkstatus { - - struct check; - --typedef void (*tree_check_fn)(struct check *c, struct node *dt); --typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node); --typedef void (*prop_check_fn)(struct check *c, struct node *dt, -- struct node *node, struct property *prop); -+typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); - - struct check { - const char *name; -- tree_check_fn tree_fn; -- node_check_fn node_fn; -- prop_check_fn prop_fn; -+ check_fn fn; - void *data; - bool warn, error; - enum checkstatus status; -@@ -58,91 +53,80 @@ struct check { - struct check **prereq; - }; - --#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \ -- static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \ -- static struct check nm = { \ -- .name = #nm, \ -- .tree_fn = (tfn), \ -- .node_fn = (nfn), \ -- .prop_fn = (pfn), \ -- .data = (d), \ -- .warn = (w), \ -- .error = (e), \ -+#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \ -+ static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \ -+ static struct check nm_ = { \ -+ .name = #nm_, \ -+ .fn = (fn_), \ -+ .data = (d_), \ -+ .warn = (w_), \ -+ .error = (e_), \ - .status = UNCHECKED, \ -- .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ -- .prereq = nm##_prereqs, \ -+ .num_prereqs = ARRAY_SIZE(nm_##_prereqs), \ -+ .prereq = nm_##_prereqs, \ - }; --#define WARNING(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__) --#define ERROR(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__) --#define CHECK(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__) -- --#define TREE_WARNING(nm, d, ...) \ -- WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define TREE_ERROR(nm, d, ...) \ -- ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define TREE_CHECK(nm, d, ...) \ -- CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define NODE_WARNING(nm, d, ...) \ -- WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define NODE_ERROR(nm, d, ...) \ -- ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define NODE_CHECK(nm, d, ...) \ -- CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define PROP_WARNING(nm, d, ...) \ -- WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) --#define PROP_ERROR(nm, d, ...) \ -- ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) --#define PROP_CHECK(nm, d, ...) \ -- CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) -- --#ifdef __GNUC__ --static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); --#endif --static inline void check_msg(struct check *c, const char *fmt, ...) -+#define WARNING(nm_, fn_, d_, ...) \ -+ CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__) -+#define ERROR(nm_, fn_, d_, ...) \ -+ CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__) -+#define CHECK(nm_, fn_, d_, ...) \ -+ CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__) -+ -+static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, -+ struct node *node, -+ struct property *prop, -+ const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); - - if ((c->warn && (quiet < 1)) - || (c->error && (quiet < 2))) { -- fprintf(stderr, "%s (%s): ", -+ fprintf(stderr, "%s: %s (%s): ", -+ strcmp(dti->outname, "-") ? dti->outname : "", - (c->error) ? "ERROR" : "Warning", c->name); -+ if (node) { -+ fprintf(stderr, "%s", node->fullpath); -+ if (prop) -+ fprintf(stderr, ":%s", prop->name); -+ fputs(": ", stderr); -+ } - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } -+ va_end(ap); - } - --#define FAIL(c, ...) \ -- do { \ -- TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -- (c)->status = FAILED; \ -- check_msg((c), __VA_ARGS__); \ -+#define FAIL(c, dti, node, ...) \ -+ do { \ -+ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -+ (c)->status = FAILED; \ -+ check_msg((c), dti, node, NULL, __VA_ARGS__); \ - } while (0) - --static void check_nodes_props(struct check *c, struct node *dt, struct node *node) -+#define FAIL_PROP(c, dti, node, prop, ...) \ -+ do { \ -+ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -+ (c)->status = FAILED; \ -+ check_msg((c), dti, node, prop, __VA_ARGS__); \ -+ } while (0) -+ -+ -+static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) - { - struct node *child; -- struct property *prop; - - TRACE(c, "%s", node->fullpath); -- if (c->node_fn) -- c->node_fn(c, dt, node); -- -- if (c->prop_fn) -- for_each_property(node, prop) { -- TRACE(c, "%s\t'%s'", node->fullpath, prop->name); -- c->prop_fn(c, dt, node, prop); -- } -+ if (c->fn) -+ c->fn(c, dti, node); - - for_each_child(node, child) -- check_nodes_props(c, dt, child); -+ check_nodes_props(c, dti, child); - } - --static bool run_check(struct check *c, struct node *dt) -+static bool run_check(struct check *c, struct dt_info *dti) - { -+ struct node *dt = dti->dt; - bool error = false; - int i; - -@@ -155,10 +139,10 @@ static bool run_check(struct check *c, struct node *dt) - - for (i = 0; i < c->num_prereqs; i++) { - struct check *prq = c->prereq[i]; -- error = error || run_check(prq, dt); -+ error = error || run_check(prq, dti); - if (prq->status != PASSED) { - c->status = PREREQ; -- check_msg(c, "Failed prerequisite '%s'", -+ check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", - c->prereq[i]->name); - } - } -@@ -166,11 +150,8 @@ static bool run_check(struct check *c, struct node *dt) - if (c->status != UNCHECKED) - goto out; - -- if (c->node_fn || c->prop_fn) -- check_nodes_props(c, dt, dt); -+ check_nodes_props(c, dti, dt); - -- if (c->tree_fn) -- c->tree_fn(c, dt); - if (c->status == UNCHECKED) - c->status = PASSED; - -@@ -188,13 +169,14 @@ out: - */ - - /* A check which always fails, for testing purposes only */ --static inline void check_always_fail(struct check *c, struct node *dt) -+static inline void check_always_fail(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- FAIL(c, "always_fail check"); -+ FAIL(c, dti, node, "always_fail check"); - } --TREE_CHECK(always_fail, NULL); -+CHECK(always_fail, check_always_fail, NULL); - --static void check_is_string(struct check *c, struct node *root, -+static void check_is_string(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -205,15 +187,43 @@ static void check_is_string(struct check *c, struct node *root, - return; /* Not present, assumed ok */ - - if (!data_is_one_string(prop->val)) -- FAIL(c, "\"%s\" property in %s is not a string", -- propname, node->fullpath); -+ FAIL_PROP(c, dti, node, prop, "property is not a string"); - } - #define WARNING_IF_NOT_STRING(nm, propname) \ -- WARNING(nm, NULL, check_is_string, NULL, (propname)) -+ WARNING(nm, check_is_string, (propname)) - #define ERROR_IF_NOT_STRING(nm, propname) \ -- ERROR(nm, NULL, check_is_string, NULL, (propname)) -+ ERROR(nm, check_is_string, (propname)) -+ -+static void check_is_string_list(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ int rem, l; -+ struct property *prop; -+ char *propname = c->data; -+ char *str; -+ -+ prop = get_property(node, propname); -+ if (!prop) -+ return; /* Not present, assumed ok */ -+ -+ str = prop->val.val; -+ rem = prop->val.len; -+ while (rem > 0) { -+ l = strnlen(str, rem); -+ if (l == rem) { -+ FAIL_PROP(c, dti, node, prop, "property is not a string list"); -+ break; -+ } -+ rem -= l + 1; -+ str += l + 1; -+ } -+} -+#define WARNING_IF_NOT_STRING_LIST(nm, propname) \ -+ WARNING(nm, check_is_string_list, (propname)) -+#define ERROR_IF_NOT_STRING_LIST(nm, propname) \ -+ ERROR(nm, check_is_string_list, (propname)) - --static void check_is_cell(struct check *c, struct node *root, -+static void check_is_cell(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -224,19 +234,18 @@ static void check_is_cell(struct check *c, struct node *root, - return; /* Not present, assumed ok */ - - if (prop->val.len != sizeof(cell_t)) -- FAIL(c, "\"%s\" property in %s is not a single cell", -- propname, node->fullpath); -+ FAIL_PROP(c, dti, node, prop, "property is not a single cell"); - } - #define WARNING_IF_NOT_CELL(nm, propname) \ -- WARNING(nm, NULL, check_is_cell, NULL, (propname)) -+ WARNING(nm, check_is_cell, (propname)) - #define ERROR_IF_NOT_CELL(nm, propname) \ -- ERROR(nm, NULL, check_is_cell, NULL, (propname)) -+ ERROR(nm, check_is_cell, (propname)) - - /* - * Structural check functions - */ - --static void check_duplicate_node_names(struct check *c, struct node *dt, -+static void check_duplicate_node_names(struct check *c, struct dt_info *dti, - struct node *node) - { - struct node *child, *child2; -@@ -246,12 +255,11 @@ static void check_duplicate_node_names(struct check *c, struct node *dt, - child2; - child2 = child2->next_sibling) - if (streq(child->name, child2->name)) -- FAIL(c, "Duplicate node name %s", -- child->fullpath); -+ FAIL(c, dti, node, "Duplicate node name"); - } --NODE_ERROR(duplicate_node_names, NULL); -+ERROR(duplicate_node_names, check_duplicate_node_names, NULL); - --static void check_duplicate_property_names(struct check *c, struct node *dt, -+static void check_duplicate_property_names(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop, *prop2; -@@ -261,48 +269,116 @@ static void check_duplicate_property_names(struct check *c, struct node *dt, - if (prop2->deleted) - continue; - if (streq(prop->name, prop2->name)) -- FAIL(c, "Duplicate property name %s in %s", -- prop->name, node->fullpath); -+ FAIL_PROP(c, dti, node, prop, "Duplicate property name"); - } - } - } --NODE_ERROR(duplicate_property_names, NULL); -+ERROR(duplicate_property_names, check_duplicate_property_names, NULL); - - #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" - #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - #define DIGITS "0123456789" - #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" -+#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" - --static void check_node_name_chars(struct check *c, struct node *dt, -+static void check_node_name_chars(struct check *c, struct dt_info *dti, - struct node *node) - { - int n = strspn(node->name, c->data); - - if (n < strlen(node->name)) -- FAIL(c, "Bad character '%c' in node %s", -- node->name[n], node->fullpath); -+ FAIL(c, dti, node, "Bad character '%c' in node name", -+ node->name[n]); - } --NODE_ERROR(node_name_chars, PROPNODECHARS "@"); -+ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); - --static void check_node_name_format(struct check *c, struct node *dt, -+static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ int n = strspn(node->name, c->data); -+ -+ if (n < node->basenamelen) -+ FAIL(c, dti, node, "Character '%c' not recommended in node name", -+ node->name[n]); -+} -+CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); -+ -+static void check_node_name_format(struct check *c, struct dt_info *dti, - struct node *node) - { - if (strchr(get_unitname(node), '@')) -- FAIL(c, "Node %s has multiple '@' characters in name", -- node->fullpath); -+ FAIL(c, dti, node, "multiple '@' characters in node name"); -+} -+ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); -+ -+static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ const char *unitname = get_unitname(node); -+ struct property *prop = get_property(node, "reg"); -+ -+ if (!prop) { -+ prop = get_property(node, "ranges"); -+ if (prop && !prop->val.len) -+ prop = NULL; -+ } -+ -+ if (prop) { -+ if (!unitname[0]) -+ FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); -+ } else { -+ if (unitname[0]) -+ FAIL(c, dti, node, "node has a unit name, but no reg property"); -+ } -+} -+WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); -+ -+static void check_property_name_chars(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ int n = strspn(prop->name, c->data); -+ -+ if (n < strlen(prop->name)) -+ FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", -+ prop->name[n]); -+ } - } --NODE_ERROR(node_name_format, NULL, &node_name_chars); -+ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); - --static void check_property_name_chars(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void check_property_name_chars_strict(struct check *c, -+ struct dt_info *dti, -+ struct node *node) - { -- int n = strspn(prop->name, c->data); -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ const char *name = prop->name; -+ int n = strspn(name, c->data); - -- if (n < strlen(prop->name)) -- FAIL(c, "Bad character '%c' in property name \"%s\", node %s", -- prop->name[n], prop->name, node->fullpath); -+ if (n == strlen(prop->name)) -+ continue; -+ -+ /* Certain names are whitelisted */ -+ if (streq(name, "device_type")) -+ continue; -+ -+ /* -+ * # is only allowed at the beginning of property names not counting -+ * the vendor prefix. -+ */ -+ if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { -+ name += n + 1; -+ n = strspn(name, c->data); -+ } -+ if (n < strlen(name)) -+ FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", -+ name[n]); -+ } - } --PROP_ERROR(property_name_chars, PROPNODECHARS); -+CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); - - #define DESCLABEL_FMT "%s%s%s%s%s" - #define DESCLABEL_ARGS(node,prop,mark) \ -@@ -311,10 +387,11 @@ PROP_ERROR(property_name_chars, PROPNODECHARS); - ((prop) ? (prop)->name : ""), \ - ((prop) ? "' in " : ""), (node)->fullpath - --static void check_duplicate_label(struct check *c, struct node *dt, -+static void check_duplicate_label(struct check *c, struct dt_info *dti, - const char *label, struct node *node, - struct property *prop, struct marker *mark) - { -+ struct node *dt = dti->dt; - struct node *othernode = NULL; - struct property *otherprop = NULL; - struct marker *othermark = NULL; -@@ -331,50 +408,49 @@ static void check_duplicate_label(struct check *c, struct node *dt, - return; - - if ((othernode != node) || (otherprop != prop) || (othermark != mark)) -- FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT -+ FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT - " and " DESCLABEL_FMT, - label, DESCLABEL_ARGS(node, prop, mark), - DESCLABEL_ARGS(othernode, otherprop, othermark)); - } - --static void check_duplicate_label_node(struct check *c, struct node *dt, -+static void check_duplicate_label_node(struct check *c, struct dt_info *dti, - struct node *node) - { - struct label *l; -+ struct property *prop; - - for_each_label(node->labels, l) -- check_duplicate_label(c, dt, l->label, node, NULL, NULL); --} --static void check_duplicate_label_prop(struct check *c, struct node *dt, -- struct node *node, struct property *prop) --{ -- struct marker *m = prop->val.markers; -- struct label *l; -+ check_duplicate_label(c, dti, l->label, node, NULL, NULL); -+ -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; - -- for_each_label(prop->labels, l) -- check_duplicate_label(c, dt, l->label, node, prop, NULL); -+ for_each_label(prop->labels, l) -+ check_duplicate_label(c, dti, l->label, node, prop, NULL); - -- for_each_marker_of_type(m, LABEL) -- check_duplicate_label(c, dt, m->ref, node, prop, m); -+ for_each_marker_of_type(m, LABEL) -+ check_duplicate_label(c, dti, m->ref, node, prop, m); -+ } - } --ERROR(duplicate_label, NULL, check_duplicate_label_node, -- check_duplicate_label_prop, NULL); -+ERROR(duplicate_label, check_duplicate_label_node, NULL); - --static void check_explicit_phandles(struct check *c, struct node *root, -- struct node *node, struct property *prop) -+static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, -+ struct node *node, const char *propname) - { -+ struct node *root = dti->dt; -+ struct property *prop; - struct marker *m; -- struct node *other; - cell_t phandle; - -- if (!streq(prop->name, "phandle") -- && !streq(prop->name, "linux,phandle")) -- return; -+ prop = get_property(node, propname); -+ if (!prop) -+ return 0; - - if (prop->val.len != sizeof(cell_t)) { -- FAIL(c, "%s has bad length (%d) %s property", -- node->fullpath, prop->val.len, prop->name); -- return; -+ FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", -+ prop->val.len, prop->name); -+ return 0; - } - - m = prop->val.markers; -@@ -384,42 +460,65 @@ static void check_explicit_phandles(struct check *c, struct node *root, - /* "Set this node's phandle equal to some - * other node's phandle". That's nonsensical - * by construction. */ { -- FAIL(c, "%s in %s is a reference to another node", -- prop->name, node->fullpath); -- return; -+ FAIL(c, dti, node, "%s is a reference to another node", -+ prop->name); - } - /* But setting this node's phandle equal to its own - * phandle is allowed - that means allocate a unique - * phandle for this node, even if it's not otherwise - * referenced. The value will be filled in later, so -- * no further checking for now. */ -- return; -+ * we treat it as having no phandle data for now. */ -+ return 0; - } - - phandle = propval_cell(prop); - - if ((phandle == 0) || (phandle == -1)) { -- FAIL(c, "%s has bad value (0x%x) in %s property", -- node->fullpath, phandle, prop->name); -- return; -+ FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", -+ phandle, prop->name); -+ return 0; - } - -- if (node->phandle && (node->phandle != phandle)) -- FAIL(c, "%s has %s property which replaces existing phandle information", -- node->fullpath, prop->name); -+ return phandle; -+} -+ -+static void check_explicit_phandles(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct node *root = dti->dt; -+ struct node *other; -+ cell_t phandle, linux_phandle; -+ -+ /* Nothing should have assigned phandles yet */ -+ assert(!node->phandle); -+ -+ phandle = check_phandle_prop(c, dti, node, "phandle"); -+ -+ linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); -+ -+ if (!phandle && !linux_phandle) -+ /* No valid phandles; nothing further to check */ -+ return; -+ -+ if (linux_phandle && phandle && (phandle != linux_phandle)) -+ FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" -+ " properties"); -+ -+ if (linux_phandle && !phandle) -+ phandle = linux_phandle; - - other = get_node_by_phandle(root, phandle); - if (other && (other != node)) { -- FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", -- node->fullpath, phandle, other->fullpath); -+ FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", -+ phandle, other->fullpath); - return; - } - - node->phandle = phandle; - } --PROP_ERROR(explicit_phandles, NULL); -+ERROR(explicit_phandles, check_explicit_phandles, NULL); - --static void check_name_properties(struct check *c, struct node *root, -+static void check_name_properties(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property **pp, *prop = NULL; -@@ -435,8 +534,8 @@ static void check_name_properties(struct check *c, struct node *root, - - if ((prop->val.len != node->basenamelen+1) - || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { -- FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" -- " of base node name)", node->fullpath, prop->val.val); -+ FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" -+ " of base node name)", prop->val.val); - } else { - /* The name property is correct, and therefore redundant. - * Delete it */ -@@ -447,60 +546,73 @@ static void check_name_properties(struct check *c, struct node *root, - } - } - ERROR_IF_NOT_STRING(name_is_string, "name"); --NODE_ERROR(name_properties, NULL, &name_is_string); -+ERROR(name_properties, check_name_properties, NULL, &name_is_string); - - /* - * Reference fixup functions - */ - --static void fixup_phandle_references(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void fixup_phandle_references(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- struct marker *m = prop->val.markers; -- struct node *refnode; -- cell_t phandle; -+ struct node *dt = dti->dt; -+ struct property *prop; - -- for_each_marker_of_type(m, REF_PHANDLE) { -- assert(m->offset + sizeof(cell_t) <= prop->val.len); -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ cell_t phandle; -+ -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ assert(m->offset + sizeof(cell_t) <= prop->val.len); -+ -+ refnode = get_node_by_ref(dt, m->ref); -+ if (! refnode) { -+ if (!(dti->dtsflags & DTSF_PLUGIN)) -+ FAIL(c, dti, node, "Reference to non-existent node or " -+ "label \"%s\"\n", m->ref); -+ else /* mark the entry as unresolved */ -+ *((fdt32_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(0xffffffff); -+ continue; -+ } - -- refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -- FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -- continue; -+ phandle = get_node_phandle(dt, refnode); -+ *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } -- -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } - } --ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -+ERROR(phandle_references, fixup_phandle_references, NULL, - &duplicate_node_names, &explicit_phandles); - --static void fixup_path_references(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void fixup_path_references(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- struct marker *m = prop->val.markers; -- struct node *refnode; -- char *path; -+ struct node *dt = dti->dt; -+ struct property *prop; - -- for_each_marker_of_type(m, REF_PATH) { -- assert(m->offset <= prop->val.len); -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ char *path; - -- refnode = get_node_by_ref(dt, m->ref); -- if (!refnode) { -- FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -- continue; -- } -+ for_each_marker_of_type(m, REF_PATH) { -+ assert(m->offset <= prop->val.len); - -- path = refnode->fullpath; -- prop->val = data_insert_at_marker(prop->val, m, path, -- strlen(path) + 1); -+ refnode = get_node_by_ref(dt, m->ref); -+ if (!refnode) { -+ FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", -+ m->ref); -+ continue; -+ } -+ -+ path = refnode->fullpath; -+ prop->val = data_insert_at_marker(prop->val, m, path, -+ strlen(path) + 1); -+ } - } - } --ERROR(path_references, NULL, NULL, fixup_path_references, NULL, -- &duplicate_node_names); -+ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); - - /* - * Semantic checks -@@ -512,8 +624,47 @@ WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); - WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); - WARNING_IF_NOT_STRING(model_is_string, "model"); - WARNING_IF_NOT_STRING(status_is_string, "status"); -+WARNING_IF_NOT_STRING(label_is_string, "label"); -+ -+WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); -+ -+static void check_names_is_string_list(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ const char *s = strrchr(prop->name, '-'); -+ if (!s || !streq(s, "-names")) -+ continue; -+ -+ c->data = prop->name; -+ check_is_string_list(c, dti, node); -+ } -+} -+WARNING(names_is_string_list, check_names_is_string_list, NULL); -+ -+static void check_alias_paths(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; - --static void fixup_addr_size_cells(struct check *c, struct node *dt, -+ if (!streq(node->name, "aliases")) -+ return; -+ -+ for_each_property(node, prop) { -+ if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { -+ FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", -+ prop->val.val); -+ continue; -+ } -+ if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) -+ FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); -+ } -+} -+WARNING(alias_paths, check_alias_paths, NULL); -+ -+static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -529,7 +680,7 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt, - if (prop) - node->size_cells = propval_cell(prop); - } --WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, -+WARNING(addr_size_cells, fixup_addr_size_cells, NULL, - &address_cells_is_cell, &size_cells_is_cell); - - #define node_addr_cells(n) \ -@@ -537,7 +688,7 @@ WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, - #define node_size_cells(n) \ - (((n)->size_cells == -1) ? 1 : (n)->size_cells) - --static void check_reg_format(struct check *c, struct node *dt, -+static void check_reg_format(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -548,25 +699,25 @@ static void check_reg_format(struct check *c, struct node *dt, - return; /* No "reg", that's fine */ - - if (!node->parent) { -- FAIL(c, "Root node has a \"reg\" property"); -+ FAIL(c, dti, node, "Root node has a \"reg\" property"); - return; - } - - if (prop->val.len == 0) -- FAIL(c, "\"reg\" property in %s is empty", node->fullpath); -+ FAIL_PROP(c, dti, node, prop, "property is empty"); - - addr_cells = node_addr_cells(node->parent); - size_cells = node_size_cells(node->parent); - entrylen = (addr_cells + size_cells) * sizeof(cell_t); - -- if ((prop->val.len % entrylen) != 0) -- FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " -- "(#address-cells == %d, #size-cells == %d)", -- node->fullpath, prop->val.len, addr_cells, size_cells); -+ if (!entrylen || (prop->val.len % entrylen) != 0) -+ FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " -+ "(#address-cells == %d, #size-cells == %d)", -+ prop->val.len, addr_cells, size_cells); - } --NODE_WARNING(reg_format, NULL, &addr_size_cells); -+WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); - --static void check_ranges_format(struct check *c, struct node *dt, -+static void check_ranges_format(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -577,7 +728,7 @@ static void check_ranges_format(struct check *c, struct node *dt, - return; - - if (!node->parent) { -- FAIL(c, "Root node has a \"ranges\" property"); -+ FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); - return; - } - -@@ -589,28 +740,237 @@ static void check_ranges_format(struct check *c, struct node *dt, - - if (prop->val.len == 0) { - if (p_addr_cells != c_addr_cells) -- FAIL(c, "%s has empty \"ranges\" property but its " -- "#address-cells (%d) differs from %s (%d)", -- node->fullpath, c_addr_cells, node->parent->fullpath, -- p_addr_cells); -+ FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " -+ "#address-cells (%d) differs from %s (%d)", -+ c_addr_cells, node->parent->fullpath, -+ p_addr_cells); - if (p_size_cells != c_size_cells) -- FAIL(c, "%s has empty \"ranges\" property but its " -- "#size-cells (%d) differs from %s (%d)", -- node->fullpath, c_size_cells, node->parent->fullpath, -- p_size_cells); -+ FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " -+ "#size-cells (%d) differs from %s (%d)", -+ c_size_cells, node->parent->fullpath, -+ p_size_cells); - } else if ((prop->val.len % entrylen) != 0) { -- FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " -- "(parent #address-cells == %d, child #address-cells == %d, " -- "#size-cells == %d)", node->fullpath, prop->val.len, -- p_addr_cells, c_addr_cells, c_size_cells); -+ FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " -+ "(parent #address-cells == %d, child #address-cells == %d, " -+ "#size-cells == %d)", prop->val.len, -+ p_addr_cells, c_addr_cells, c_size_cells); -+ } -+} -+WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); -+ -+static const struct bus_type pci_bus = { -+ .name = "PCI", -+}; -+ -+static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) -+{ -+ struct property *prop; -+ cell_t *cells; -+ -+ prop = get_property(node, "device_type"); -+ if (!prop || !streq(prop->val.val, "pci")) -+ return; -+ -+ node->bus = &pci_bus; -+ -+ if (!strprefixeq(node->name, node->basenamelen, "pci") && -+ !strprefixeq(node->name, node->basenamelen, "pcie")) -+ FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); -+ -+ prop = get_property(node, "ranges"); -+ if (!prop) -+ FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); -+ -+ if (node_addr_cells(node) != 3) -+ FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); -+ if (node_size_cells(node) != 2) -+ FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); -+ -+ prop = get_property(node, "bus-range"); -+ if (!prop) -+ return; -+ -+ if (prop->val.len != (sizeof(cell_t) * 2)) { -+ FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); -+ return; -+ } -+ cells = (cell_t *)prop->val.val; -+ if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) -+ FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); -+ if (fdt32_to_cpu(cells[1]) > 0xff) -+ FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); -+} -+WARNING(pci_bridge, check_pci_bridge, NULL, -+ &device_type_is_string, &addr_size_cells); -+ -+static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) -+{ -+ struct property *prop; -+ unsigned int bus_num, min_bus, max_bus; -+ cell_t *cells; -+ -+ if (!node->parent || (node->parent->bus != &pci_bus)) -+ return; -+ -+ prop = get_property(node, "reg"); -+ if (!prop) -+ return; -+ -+ cells = (cell_t *)prop->val.val; -+ bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; -+ -+ prop = get_property(node->parent, "bus-range"); -+ if (!prop) { -+ min_bus = max_bus = 0; -+ } else { -+ cells = (cell_t *)prop->val.val; -+ min_bus = fdt32_to_cpu(cells[0]); -+ max_bus = fdt32_to_cpu(cells[0]); -+ } -+ if ((bus_num < min_bus) || (bus_num > max_bus)) -+ FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", -+ bus_num, min_bus, max_bus); -+} -+WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); -+ -+static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) -+{ -+ struct property *prop; -+ const char *unitname = get_unitname(node); -+ char unit_addr[5]; -+ unsigned int dev, func, reg; -+ cell_t *cells; -+ -+ if (!node->parent || (node->parent->bus != &pci_bus)) -+ return; -+ -+ prop = get_property(node, "reg"); -+ if (!prop) { -+ FAIL(c, dti, node, "missing PCI reg property"); -+ return; -+ } -+ -+ cells = (cell_t *)prop->val.val; -+ if (cells[1] || cells[2]) -+ FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); -+ -+ reg = fdt32_to_cpu(cells[0]); -+ dev = (reg & 0xf800) >> 11; -+ func = (reg & 0x700) >> 8; -+ -+ if (reg & 0xff000000) -+ FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); -+ if (reg & 0x000000ff) -+ FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); -+ -+ if (func == 0) { -+ snprintf(unit_addr, sizeof(unit_addr), "%x", dev); -+ if (streq(unitname, unit_addr)) -+ return; -+ } -+ -+ snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); -+ if (streq(unitname, unit_addr)) -+ return; -+ -+ FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", -+ unit_addr); -+} -+WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); -+ -+static const struct bus_type simple_bus = { -+ .name = "simple-bus", -+}; -+ -+static bool node_is_compatible(struct node *node, const char *compat) -+{ -+ struct property *prop; -+ const char *str, *end; -+ -+ prop = get_property(node, "compatible"); -+ if (!prop) -+ return false; -+ -+ for (str = prop->val.val, end = str + prop->val.len; str < end; -+ str += strnlen(str, end - str) + 1) { -+ if (strprefixeq(str, end - str, compat)) -+ return true; - } -+ return false; -+} -+ -+static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) -+{ -+ if (node_is_compatible(node, "simple-bus")) -+ node->bus = &simple_bus; - } --NODE_WARNING(ranges_format, NULL, &addr_size_cells); -+WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); -+ -+static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) -+{ -+ struct property *prop; -+ const char *unitname = get_unitname(node); -+ char unit_addr[17]; -+ unsigned int size; -+ uint64_t reg = 0; -+ cell_t *cells = NULL; -+ -+ if (!node->parent || (node->parent->bus != &simple_bus)) -+ return; -+ -+ prop = get_property(node, "reg"); -+ if (prop) -+ cells = (cell_t *)prop->val.val; -+ else { -+ prop = get_property(node, "ranges"); -+ if (prop && prop->val.len) -+ /* skip of child address */ -+ cells = ((cell_t *)prop->val.val) + node_addr_cells(node); -+ } -+ -+ if (!cells) { -+ if (node->parent->parent && !(node->bus == &simple_bus)) -+ FAIL(c, dti, node, "missing or empty reg/ranges property"); -+ return; -+ } -+ -+ size = node_addr_cells(node->parent); -+ while (size--) -+ reg = (reg << 32) | fdt32_to_cpu(*(cells++)); -+ -+ snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); -+ if (!streq(unitname, unit_addr)) -+ FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", -+ unit_addr); -+} -+WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); -+ -+static void check_unit_address_format(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ const char *unitname = get_unitname(node); -+ -+ if (node->parent && node->parent->bus) -+ return; -+ -+ if (!unitname[0]) -+ return; -+ -+ if (!strncmp(unitname, "0x", 2)) { -+ FAIL(c, dti, node, "unit name should not have leading \"0x\""); -+ /* skip over 0x for next test */ -+ unitname += 2; -+ } -+ if (unitname[0] == '0' && isxdigit(unitname[1])) -+ FAIL(c, dti, node, "unit name should not have leading 0s"); -+} -+WARNING(unit_address_format, check_unit_address_format, NULL, -+ &node_name_format, &pci_bridge, &simple_bus_bridge); - - /* - * Style checks - */ --static void check_avoid_default_addr_size(struct check *c, struct node *dt, -+static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *reg, *ranges; -@@ -625,31 +985,377 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, - return; - - if (node->parent->addr_cells == -1) -- FAIL(c, "Relying on default #address-cells value for %s", -- node->fullpath); -+ FAIL(c, dti, node, "Relying on default #address-cells value"); - - if (node->parent->size_cells == -1) -- FAIL(c, "Relying on default #size-cells value for %s", -- node->fullpath); -+ FAIL(c, dti, node, "Relying on default #size-cells value"); -+} -+WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, -+ &addr_size_cells); -+ -+static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ struct node *child; -+ bool has_reg = false; -+ -+ if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) -+ return; -+ -+ if (get_property(node, "ranges") || !node->children) -+ return; -+ -+ for_each_child(node, child) { -+ prop = get_property(child, "reg"); -+ if (prop) -+ has_reg = true; -+ } -+ -+ if (!has_reg) -+ FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); - } --NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells); -+WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); - - static void check_obsolete_chosen_interrupt_controller(struct check *c, -- struct node *dt) -+ struct dt_info *dti, -+ struct node *node) - { -+ struct node *dt = dti->dt; - struct node *chosen; - struct property *prop; - -+ if (node != dt) -+ return; -+ -+ - chosen = get_node_by_path(dt, "/chosen"); - if (!chosen) - return; - - prop = get_property(chosen, "interrupt-controller"); - if (prop) -- FAIL(c, "/chosen has obsolete \"interrupt-controller\" " -- "property"); -+ FAIL_PROP(c, dti, node, prop, -+ "/chosen has obsolete \"interrupt-controller\" property"); -+} -+WARNING(obsolete_chosen_interrupt_controller, -+ check_obsolete_chosen_interrupt_controller, NULL); -+ -+static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ if (!streq(node->name, "chosen")) -+ return; -+ -+ if (node->parent != dti->dt) -+ FAIL(c, dti, node, "chosen node must be at root node"); - } --TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); -+WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); -+ -+static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ if (!streq(node->name, "chosen")) -+ return; -+ -+ prop = get_property(node, "bootargs"); -+ if (!prop) -+ return; -+ -+ c->data = prop->name; -+ check_is_string(c, dti, node); -+} -+WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); -+ -+static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ if (!streq(node->name, "chosen")) -+ return; -+ -+ prop = get_property(node, "stdout-path"); -+ if (!prop) { -+ prop = get_property(node, "linux,stdout-path"); -+ if (!prop) -+ return; -+ FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); -+ } -+ -+ c->data = prop->name; -+ check_is_string(c, dti, node); -+} -+WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); -+ -+struct provider { -+ const char *prop_name; -+ const char *cell_name; -+ bool optional; -+}; -+ -+static void check_property_phandle_args(struct check *c, -+ struct dt_info *dti, -+ struct node *node, -+ struct property *prop, -+ const struct provider *provider) -+{ -+ struct node *root = dti->dt; -+ int cell, cellsize = 0; -+ -+ if (prop->val.len % sizeof(cell_t)) { -+ FAIL_PROP(c, dti, node, prop, -+ "property size (%d) is invalid, expected multiple of %zu", -+ prop->val.len, sizeof(cell_t)); -+ return; -+ } -+ -+ for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { -+ struct node *provider_node; -+ struct property *cellprop; -+ int phandle; -+ -+ phandle = propval_cell_n(prop, cell); -+ /* -+ * Some bindings use a cell value 0 or -1 to skip over optional -+ * entries when each index position has a specific definition. -+ */ -+ if (phandle == 0 || phandle == -1) { -+ /* Give up if this is an overlay with external references */ -+ if (dti->dtsflags & DTSF_PLUGIN) -+ break; -+ -+ cellsize = 0; -+ continue; -+ } -+ -+ /* If we have markers, verify the current cell is a phandle */ -+ if (prop->val.markers) { -+ struct marker *m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ if (m->offset == (cell * sizeof(cell_t))) -+ break; -+ } -+ if (!m) -+ FAIL_PROP(c, dti, node, prop, -+ "cell %d is not a phandle reference", -+ cell); -+ } -+ -+ provider_node = get_node_by_phandle(root, phandle); -+ if (!provider_node) { -+ FAIL_PROP(c, dti, node, prop, -+ "Could not get phandle node for (cell %d)", -+ cell); -+ break; -+ } -+ -+ cellprop = get_property(provider_node, provider->cell_name); -+ if (cellprop) { -+ cellsize = propval_cell(cellprop); -+ } else if (provider->optional) { -+ cellsize = 0; -+ } else { -+ FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", -+ provider->cell_name, -+ provider_node->fullpath, -+ prop->name, cell); -+ break; -+ } -+ -+ if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { -+ FAIL_PROP(c, dti, node, prop, -+ "property size (%d) too small for cell size %d", -+ prop->val.len, cellsize); -+ } -+ } -+} -+ -+static void check_provider_cells_property(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ struct provider *provider = c->data; -+ struct property *prop; -+ -+ prop = get_property(node, provider->prop_name); -+ if (!prop) -+ return; -+ -+ check_property_phandle_args(c, dti, node, prop, provider); -+} -+#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ -+ static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ -+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); -+ -+WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); -+WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); -+WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); -+ -+static bool prop_is_gpio(struct property *prop) -+{ -+ char *str; -+ -+ /* -+ * *-gpios and *-gpio can appear in property names, -+ * so skip over any false matches (only one known ATM) -+ */ -+ if (strstr(prop->name, "nr-gpio")) -+ return false; -+ -+ str = strrchr(prop->name, '-'); -+ if (str) -+ str++; -+ else -+ str = prop->name; -+ if (!(streq(str, "gpios") || streq(str, "gpio"))) -+ return false; -+ -+ return true; -+} -+ -+static void check_gpios_property(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ /* Skip GPIO hog nodes which have 'gpios' property */ -+ if (get_property(node, "gpio-hog")) -+ return; -+ -+ for_each_property(node, prop) { -+ struct provider provider; -+ -+ if (!prop_is_gpio(prop)) -+ continue; -+ -+ provider.prop_name = prop->name; -+ provider.cell_name = "#gpio-cells"; -+ provider.optional = false; -+ check_property_phandle_args(c, dti, node, prop, &provider); -+ } -+ -+} -+WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); -+ -+static void check_deprecated_gpio_property(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ char *str; -+ -+ if (!prop_is_gpio(prop)) -+ continue; -+ -+ str = strstr(prop->name, "gpio"); -+ if (!streq(str, "gpio")) -+ continue; -+ -+ FAIL_PROP(c, dti, node, prop, -+ "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); -+ } -+ -+} -+CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); -+ -+static bool node_is_interrupt_provider(struct node *node) -+{ -+ struct property *prop; -+ -+ prop = get_property(node, "interrupt-controller"); -+ if (prop) -+ return true; -+ -+ prop = get_property(node, "interrupt-map"); -+ if (prop) -+ return true; -+ -+ return false; -+} -+static void check_interrupts_property(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ struct node *root = dti->dt; -+ struct node *irq_node = NULL, *parent = node; -+ struct property *irq_prop, *prop = NULL; -+ int irq_cells, phandle; -+ -+ irq_prop = get_property(node, "interrupts"); -+ if (!irq_prop) -+ return; -+ -+ if (irq_prop->val.len % sizeof(cell_t)) -+ FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", -+ irq_prop->val.len, sizeof(cell_t)); -+ -+ while (parent && !prop) { -+ if (parent != node && node_is_interrupt_provider(parent)) { -+ irq_node = parent; -+ break; -+ } -+ -+ prop = get_property(parent, "interrupt-parent"); -+ if (prop) { -+ phandle = propval_cell(prop); -+ /* Give up if this is an overlay with external references */ -+ if ((phandle == 0 || phandle == -1) && -+ (dti->dtsflags & DTSF_PLUGIN)) -+ return; -+ -+ irq_node = get_node_by_phandle(root, phandle); -+ if (!irq_node) { -+ FAIL_PROP(c, dti, parent, prop, "Bad phandle"); -+ return; -+ } -+ if (!node_is_interrupt_provider(irq_node)) -+ FAIL(c, dti, irq_node, -+ "Missing interrupt-controller or interrupt-map property"); -+ -+ break; -+ } -+ -+ parent = parent->parent; -+ } -+ -+ if (!irq_node) { -+ FAIL(c, dti, node, "Missing interrupt-parent"); -+ return; -+ } -+ -+ prop = get_property(irq_node, "#interrupt-cells"); -+ if (!prop) { -+ FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); -+ return; -+ } -+ -+ irq_cells = propval_cell(prop); -+ if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { -+ FAIL_PROP(c, dti, node, prop, -+ "size is (%d), expected multiple of %d", -+ irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); -+ } -+} -+WARNING(interrupts_property, check_interrupts_property, &phandle_references); - - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, -@@ -663,11 +1369,52 @@ static struct check *check_table[] = { - - &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, - &device_type_is_string, &model_is_string, &status_is_string, -+ &label_is_string, -+ -+ &compatible_is_string_list, &names_is_string_list, -+ -+ &property_name_chars_strict, -+ &node_name_chars_strict, - - &addr_size_cells, ®_format, &ranges_format, - -+ &unit_address_vs_reg, -+ &unit_address_format, -+ -+ &pci_bridge, -+ &pci_device_reg, -+ &pci_device_bus_num, -+ -+ &simple_bus_bridge, -+ &simple_bus_reg, -+ - &avoid_default_addr_size, -+ &avoid_unnecessary_addr_size, - &obsolete_chosen_interrupt_controller, -+ &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, -+ -+ &clocks_property, -+ &cooling_device_property, -+ &dmas_property, -+ &hwlocks_property, -+ &interrupts_extended_property, -+ &io_channels_property, -+ &iommus_property, -+ &mboxes_property, -+ &msi_parent_property, -+ &mux_controls_property, -+ &phys_property, -+ &power_domains_property, -+ &pwms_property, -+ &resets_property, -+ &sound_dai_property, -+ &thermal_sensors_property, -+ -+ &deprecated_gpio_property, -+ &gpios_property, -+ &interrupts_property, -+ -+ &alias_paths, - - &always_fail, - }; -@@ -733,9 +1480,8 @@ void parse_checks_option(bool warn, bool error, const char *arg) - die("Unrecognized check name \"%s\"\n", name); - } - --void process_checks(bool force, struct boot_info *bi) -+void process_checks(bool force, struct dt_info *dti) - { -- struct node *dt = bi->dt; - int i; - int error = 0; - -@@ -743,7 +1489,7 @@ void process_checks(bool force, struct boot_info *bi) - struct check *c = check_table[i]; - - if (c->warn || c->error) -- error = error || run_check(c, dt); -+ error = error || run_check(c, dti); - } - - if (error) { -diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c -index 8cae23746..aa37a16c8 100644 ---- a/scripts/dtc/data.c -+++ b/scripts/dtc/data.c -@@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2) - struct data data_append_integer(struct data d, uint64_t value, int bits) - { - uint8_t value_8; -- uint16_t value_16; -- uint32_t value_32; -- uint64_t value_64; -+ fdt16_t value_16; -+ fdt32_t value_32; -+ fdt64_t value_64; - - switch (bits) { - case 8: -@@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) - } - } - --struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) -+struct data data_append_re(struct data d, uint64_t address, uint64_t size) - { -- struct fdt_reserve_entry bere; -+ struct fdt_reserve_entry re; - -- bere.address = cpu_to_fdt64(re->address); -- bere.size = cpu_to_fdt64(re->size); -+ re.address = cpu_to_fdt64(address); -+ re.size = cpu_to_fdt64(size); - -- return data_append_data(d, &bere, sizeof(bere)); -+ return data_append_data(d, &re, sizeof(re)); - } - - struct data data_append_cell(struct data d, cell_t word) -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 0ee1caf03..fd825ebba 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -62,7 +62,8 @@ static int dts_version = 1; - - static void push_input_file(const char *filename); - static bool pop_input_file(void); --static void lexical_error(const char *fmt, ...); -+static void PRINTF(1, 2) lexical_error(const char *fmt, ...); -+ - %} - - %% -@@ -73,24 +74,32 @@ static void lexical_error(const char *fmt, ...); - } - - <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { -- char *line, *tmp, *fn; -+ char *line, *fnstart, *fnend; -+ struct data fn; - /* skip text before line # */ - line = yytext; - while (!isdigit((unsigned char)*line)) - line++; -- /* skip digits in line # */ -- tmp = line; -- while (!isspace((unsigned char)*tmp)) -- tmp++; -- /* "NULL"-terminate line # */ -- *tmp = '\0'; -- /* start of filename */ -- fn = strchr(tmp + 1, '"') + 1; -- /* strip trailing " from filename */ -- tmp = strchr(fn, '"'); -- *tmp = 0; -+ -+ /* regexp ensures that first and list " -+ * in the whole yytext are those at -+ * beginning and end of the filename string */ -+ fnstart = memchr(yytext, '"', yyleng); -+ for (fnend = yytext + yyleng - 1; -+ *fnend != '"'; fnend--) -+ ; -+ assert(fnstart && fnend && (fnend > fnstart)); -+ -+ fn = data_copy_escape_string(fnstart + 1, -+ fnend - fnstart - 1); -+ -+ /* Don't allow nuls in filenames */ -+ if (memchr(fn.val, '\0', fn.len - 1)) -+ lexical_error("nul in line number directive"); -+ - /* -1 since #line is the number of the next line */ -- srcpos_set_line(xstrdup(fn), atoi(line) - 1); -+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); -+ data_free(fn); - } - - <*><> { -@@ -113,6 +122,11 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -@@ -153,7 +167,10 @@ static void lexical_error(const char *fmt, ...); - errno = 0; - yylval.integer = strtoull(yytext, &e, 0); - -- assert(!(*e) || !e[strspn(e, "UL")]); -+ if (*e && e[strspn(e, "UL")]) { -+ lexical_error("Bad integer literal '%s'", -+ yytext); -+ } - - if (errno == ERANGE) - lexical_error("Integer literal '%s' out of range", -@@ -173,16 +190,16 @@ static void lexical_error(const char *fmt, ...); - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; -- return DT_CHAR_LITERAL; -- } -- -- yylval.integer = (unsigned char)d.val[0]; -+ } else { -+ yylval.integer = (unsigned char)d.val[0]; - -- if (d.len > 2) -- lexical_error("Character literal has %d" -- " characters instead of 1", -- d.len - 1); -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ } - -+ data_free(d); - return DT_CHAR_LITERAL; - } - -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 11cd78e72..f032b24b2 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -1,6 +1,6 @@ --#line 2 "dtc-lexer.lex.c" -+#line 2 "dtc-lexer.l.c" - --#line 4 "dtc-lexer.lex.c" -+#line 4 "dtc-lexer.l.c" - - #define YY_INT_ALIGNED short int - -@@ -8,8 +8,8 @@ - - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 --#define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 39 -+#define YY_FLEX_MINOR_VERSION 6 -+#define YY_FLEX_SUBMINOR_VERSION 4 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -84,60 +84,48 @@ typedef unsigned int flex_uint32_t; - #define UINT32_MAX (4294967295U) - #endif - -+#ifndef SIZE_MAX -+#define SIZE_MAX (~(size_t)0) -+#endif -+ - #endif /* ! C99 */ - - #endif /* ! FLEXINT_H */ - --#ifdef __cplusplus -- --/* The "const" storage-class-modifier is valid. */ --#define YY_USE_CONST -- --#else /* ! __cplusplus */ -- --/* C99 requires __STDC__ to be defined as 1. */ --#if defined (__STDC__) -- --#define YY_USE_CONST -+/* begin standard C++ headers. */ - --#endif /* defined (__STDC__) */ --#endif /* ! __cplusplus */ -- --#ifdef YY_USE_CONST -+/* TODO: this is always defined, so inline it */ - #define yyconst const -+ -+#if defined(__GNUC__) && __GNUC__ >= 3 -+#define yynoreturn __attribute__((__noreturn__)) - #else --#define yyconst -+#define yynoreturn - #endif - - /* Returned upon end-of-file. */ - #define YY_NULL 0 - --/* Promotes a possibly negative, possibly signed char to an unsigned -- * integer for use as an array index. If the signed char is negative, -- * we want to instead treat it as an 8-bit unsigned char, hence the -- * double cast. -+/* Promotes a possibly negative, possibly signed char to an -+ * integer in range [0..255] for use as an array index. - */ --#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) -+#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) - - /* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ - #define BEGIN (yy_start) = 1 + 2 * -- - /* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ - #define YY_START (((yy_start) - 1) / 2) - #define YYSTATE YY_START -- - /* Action number for EOF rule of a given start state. */ - #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -- - /* Special action meaning "start processing a new file". */ --#define YY_NEW_FILE yyrestart(yyin ) -- -+#define YY_NEW_FILE yyrestart( yyin ) - #define YY_END_OF_BUFFER_CHAR 0 - - /* Size of default input buffer. */ -@@ -167,14 +155,14 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; - typedef size_t yy_size_t; - #endif - --extern yy_size_t yyleng; -+extern int yyleng; - - extern FILE *yyin, *yyout; - - #define EOB_ACT_CONTINUE_SCAN 0 - #define EOB_ACT_END_OF_FILE 1 - #define EOB_ACT_LAST_MATCH 2 -- -+ - #define YY_LESS_LINENO(n) - #define YY_LINENO_REWIND_TO(ptr) - -@@ -191,7 +179,6 @@ extern FILE *yyin, *yyout; - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) -- - #define unput(c) yyunput( c, (yytext_ptr) ) - - #ifndef YY_STRUCT_YY_BUFFER_STATE -@@ -206,12 +193,12 @@ struct yy_buffer_state - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ -- yy_size_t yy_buf_size; -+ int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- yy_size_t yy_n_chars; -+ int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -234,7 +221,7 @@ struct yy_buffer_state - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ -- -+ - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ -@@ -262,7 +249,7 @@ struct yy_buffer_state - /* Stack of input buffers. */ - static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ - static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ --static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ -+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ - - /* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general -@@ -273,7 +260,6 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) -- - /* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -@@ -281,11 +267,11 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ --yy_size_t yyleng; -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ -+int yyleng; - - /* Points to current character in buffer. */ --static char *yy_c_buf_p = (char *) 0; -+static char *yy_c_buf_p = NULL; - static int yy_init = 0; /* whether we need to initialize */ - static int yy_start = 0; /* start state number */ - -@@ -294,87 +280,83 @@ static int yy_start = 0; /* start state number */ - */ - static int yy_did_buffer_switch_on_eof; - --void yyrestart (FILE *input_file ); --void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); --YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); --void yy_delete_buffer (YY_BUFFER_STATE b ); --void yy_flush_buffer (YY_BUFFER_STATE b ); --void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); --void yypop_buffer_state (void ); -- --static void yyensure_buffer_stack (void ); --static void yy_load_buffer_state (void ); --static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -+void yyrestart ( FILE *input_file ); -+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -+void yy_delete_buffer ( YY_BUFFER_STATE b ); -+void yy_flush_buffer ( YY_BUFFER_STATE b ); -+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); -+void yypop_buffer_state ( void ); - --#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -+static void yyensure_buffer_stack ( void ); -+static void yy_load_buffer_state ( void ); -+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); -+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) - --YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); --YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); -+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); -+YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); -+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); - --void *yyalloc (yy_size_t ); --void *yyrealloc (void *,yy_size_t ); --void yyfree (void * ); -+void *yyalloc ( yy_size_t ); -+void *yyrealloc ( void *, yy_size_t ); -+void yyfree ( void * ); - - #define yy_new_buffer yy_create_buffer -- - #define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ -- yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } -- - #define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ -- yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } -- - #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - - /* Begin user sect3 */ - --#define yywrap() 1 -+#define yywrap() (/*CONSTCOND*/1) - #define YY_SKIP_YYWRAP -+typedef flex_uint8_t YY_CHAR; - --typedef unsigned char YY_CHAR; -- --FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -+FILE *yyin = NULL, *yyout = NULL; - - typedef int yy_state_type; - - extern int yylineno; -- - int yylineno = 1; - - extern char *yytext; -+#ifdef yytext_ptr -+#undef yytext_ptr -+#endif - #define yytext_ptr yytext - --static yy_state_type yy_get_previous_state (void ); --static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); --static int yy_get_next_buffer (void ); --static void yy_fatal_error (yyconst char msg[] ); -+static yy_state_type yy_get_previous_state ( void ); -+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -+static int yy_get_next_buffer ( void ); -+static void yynoreturn yy_fatal_error ( const char* msg ); - - /* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ - #define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ -- yyleng = (size_t) (yy_cp - yy_bp); \ -+ yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; -- --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -382,28 +364,29 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[159] = -+static const flex_int16_t yy_accept[166] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - --static yyconst flex_int32_t yy_ec[256] = -+static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, -@@ -416,9 +399,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,163 +418,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static const YY_CHAR yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[173] = -+static const flex_int16_t yy_base[180] = - { 0, -- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -- -- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -- 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[173] = -+static const flex_int16_t yy_def[180] = - { 0, -- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[438] = -+static const flex_int16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -- -- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -- -- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[438] = -+static const flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -- -- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -- -- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -608,7 +593,7 @@ int yy_flex_debug = 0; - #define YY_MORE_ADJ 0 - #define YY_RESTORE_YY_MORE_OFFSET - char *yytext; --#line 1 "dtc-lexer.l" -+#line 1 "" - /* - * (C) Copyright David Gibson , IBM Corporation. 2005. - * -@@ -632,7 +617,7 @@ char *yytext; - - - --#line 37 "dtc-lexer.l" -+#line 37 "" - #include "dtc.h" - #include "srcpos.h" - #include "dtc-parser.tab.h" -@@ -661,8 +646,10 @@ static int dts_version = 1; - - static void push_input_file(const char *filename); - static bool pop_input_file(void); --static void lexical_error(const char *fmt, ...); --#line 666 "dtc-lexer.lex.c" -+static void PRINTF(1, 2) lexical_error(const char *fmt, ...); -+ -+#line 652 "dtc-lexer.l.c" -+#line 653 "dtc-lexer.l.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -681,36 +668,36 @@ static void lexical_error(const char *fmt, ...); - #define YY_EXTRA_TYPE void * - #endif - --static int yy_init_globals (void ); -+static int yy_init_globals ( void ); - - /* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - --int yylex_destroy (void ); -+int yylex_destroy ( void ); - --int yyget_debug (void ); -+int yyget_debug ( void ); - --void yyset_debug (int debug_flag ); -+void yyset_debug ( int debug_flag ); - --YY_EXTRA_TYPE yyget_extra (void ); -+YY_EXTRA_TYPE yyget_extra ( void ); - --void yyset_extra (YY_EXTRA_TYPE user_defined ); -+void yyset_extra ( YY_EXTRA_TYPE user_defined ); - --FILE *yyget_in (void ); -+FILE *yyget_in ( void ); - --void yyset_in (FILE * in_str ); -+void yyset_in ( FILE * _in_str ); - --FILE *yyget_out (void ); -+FILE *yyget_out ( void ); - --void yyset_out (FILE * out_str ); -+void yyset_out ( FILE * _out_str ); - --yy_size_t yyget_leng (void ); -+ int yyget_leng ( void ); - --char *yyget_text (void ); -+char *yyget_text ( void ); - --int yyget_lineno (void ); -+int yyget_lineno ( void ); - --void yyset_lineno (int line_number ); -+void yyset_lineno ( int _line_number ); - - /* Macros after this point can all be overridden by user definitions in - * section 1. -@@ -718,26 +705,29 @@ void yyset_lineno (int line_number ); - - #ifndef YY_SKIP_YYWRAP - #ifdef __cplusplus --extern "C" int yywrap (void ); -+extern "C" int yywrap ( void ); - #else --extern int yywrap (void ); -+extern int yywrap ( void ); -+#endif - #endif -+ -+#ifndef YY_NO_UNPUT -+ - #endif - - #ifndef yytext_ptr --static void yy_flex_strncpy (char *,yyconst char *,int ); -+static void yy_flex_strncpy ( char *, const char *, int ); - #endif - - #ifdef YY_NEED_STRLEN --static int yy_flex_strlen (yyconst char * ); -+static int yy_flex_strlen ( const char * ); - #endif - - #ifndef YY_NO_INPUT -- - #ifdef __cplusplus --static int yyinput (void ); -+static int yyinput ( void ); - #else --static int input (void ); -+static int input ( void ); - #endif - - #endif -@@ -757,7 +747,7 @@ static int input (void ); - /* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ --#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) - #endif - - /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, -@@ -768,7 +758,7 @@ static int input (void ); - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ -- size_t n; \ -+ int n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ -@@ -781,7 +771,7 @@ static int input (void ); - else \ - { \ - errno=0; \ -- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ -+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ -@@ -836,7 +826,7 @@ extern int yylex (void); - - /* Code executed at the end of each rule. */ - #ifndef YY_BREAK --#define YY_BREAK break; -+#define YY_BREAK /*LINTED*/break; - #endif - - #define YY_RULE_SETUP \ -@@ -849,9 +839,9 @@ extern int yylex (void); - */ - YY_DECL - { -- register yy_state_type yy_current_state; -- register char *yy_cp, *yy_bp; -- register int yy_act; -+ yy_state_type yy_current_state; -+ char *yy_cp, *yy_bp; -+ int yy_act; - - if ( !(yy_init) ) - { -@@ -873,18 +863,18 @@ YY_DECL - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = -- yy_create_buffer(yyin,YY_BUF_SIZE ); -+ yy_create_buffer( yyin, YY_BUF_SIZE ); - } - -- yy_load_buffer_state( ); -+ yy_load_buffer_state( ); - } - - { --#line 68 "dtc-lexer.l" -+#line 69 "" - --#line 886 "dtc-lexer.lex.c" -+#line 876 "dtc-lexer.l.c" - -- while ( 1 ) /* loops until end-of-file is reached */ -+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - -@@ -901,7 +891,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; -+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -910,13 +900,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -+ if ( yy_current_state >= 166 ) -+ yy_c = yy_meta[yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 158 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -939,7 +929,7 @@ do_action: /* This label is used only to access EOF actions. */ - case 1: - /* rule 1 can match eol */ - YY_RULE_SETUP --#line 69 "dtc-lexer.l" -+#line 70 "" - { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; -@@ -949,33 +939,41 @@ YY_RULE_SETUP - case 2: - /* rule 2 can match eol */ - YY_RULE_SETUP --#line 75 "dtc-lexer.l" -+#line 76 "" - { -- char *line, *tmp, *fn; -+ char *line, *fnstart, *fnend; -+ struct data fn; - /* skip text before line # */ - line = yytext; - while (!isdigit((unsigned char)*line)) - line++; -- /* skip digits in line # */ -- tmp = line; -- while (!isspace((unsigned char)*tmp)) -- tmp++; -- /* "NULL"-terminate line # */ -- *tmp = '\0'; -- /* start of filename */ -- fn = strchr(tmp + 1, '"') + 1; -- /* strip trailing " from filename */ -- tmp = strchr(fn, '"'); -- *tmp = 0; -+ -+ /* regexp ensures that first and list " -+ * in the whole yytext are those at -+ * beginning and end of the filename string */ -+ fnstart = memchr(yytext, '"', yyleng); -+ for (fnend = yytext + yyleng - 1; -+ *fnend != '"'; fnend--) -+ ; -+ assert(fnstart && fnend && (fnend > fnstart)); -+ -+ fn = data_copy_escape_string(fnstart + 1, -+ fnend - fnstart - 1); -+ -+ /* Don't allow nuls in filenames */ -+ if (memchr(fn.val, '\0', fn.len - 1)) -+ lexical_error("nul in line number directive"); -+ - /* -1 since #line is the number of the next line */ -- srcpos_set_line(xstrdup(fn), atoi(line) - 1); -+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); -+ data_free(fn); - } - YY_BREAK - case YY_STATE_EOF(INITIAL): - case YY_STATE_EOF(BYTESTRING): - case YY_STATE_EOF(PROPNODENAME): - case YY_STATE_EOF(V1): --#line 96 "dtc-lexer.l" -+#line 105 "" - { - if (!pop_input_file()) { - yyterminate(); -@@ -985,7 +983,7 @@ case YY_STATE_EOF(V1): - case 3: - /* rule 3 can match eol */ - YY_RULE_SETUP --#line 102 "dtc-lexer.l" -+#line 111 "" - { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, -@@ -995,7 +993,7 @@ YY_RULE_SETUP - YY_BREAK - case 4: - YY_RULE_SETUP --#line 109 "dtc-lexer.l" -+#line 118 "" - { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; -@@ -1005,25 +1003,33 @@ YY_RULE_SETUP - YY_BREAK - case 5: - YY_RULE_SETUP --#line 116 "dtc-lexer.l" -+#line 125 "" -+{ -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 130 "" - { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 122 "dtc-lexer.l" -+#line 136 "" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 128 "dtc-lexer.l" -+#line 142 "" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1031,9 +1037,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 135 "dtc-lexer.l" -+#line 149 "" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1041,9 +1047,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 142 "dtc-lexer.l" -+#line 156 "" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1051,9 +1057,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 149 "dtc-lexer.l" -+#line 163 "" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1061,7 +1067,10 @@ YY_RULE_SETUP - errno = 0; - yylval.integer = strtoull(yytext, &e, 0); - -- assert(!(*e) || !e[strspn(e, "UL")]); -+ if (*e && e[strspn(e, "UL")]) { -+ lexical_error("Bad integer literal '%s'", -+ yytext); -+ } - - if (errno == ERANGE) - lexical_error("Integer literal '%s' out of range", -@@ -1073,10 +1082,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 168 "dtc-lexer.l" -+#line 185 "" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1085,31 +1094,31 @@ YY_RULE_SETUP - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; -- return DT_CHAR_LITERAL; -- } -+ } else { -+ yylval.integer = (unsigned char)d.val[0]; - -- yylval.integer = (unsigned char)d.val[0]; -- -- if (d.len > 2) -- lexical_error("Character literal has %d" -- " characters instead of 1", -- d.len - 1); -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ } - -+ data_free(d); - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 189 "dtc-lexer.l" -+#line 206 "" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 195 "dtc-lexer.l" -+#line 212 "" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1117,27 +1126,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 202 "dtc-lexer.l" -+#line 219 "" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 208 "dtc-lexer.l" -+#line 225 "" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 214 "dtc-lexer.l" -+#line 231 "" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1146,75 +1155,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 222 "dtc-lexer.l" -+#line 239 "" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 227 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 228 "dtc-lexer.l" --/* eat C-style comments */ -+#line 244 "" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 229 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 245 "" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 231 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 246 "" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 232 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 248 "" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 233 "dtc-lexer.l" --{ return DT_LE; }; -+#line 249 "" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 234 "dtc-lexer.l" --{ return DT_GE; }; -+#line 250 "" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 235 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 251 "" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 236 "dtc-lexer.l" --{ return DT_NE; }; -+#line 252 "" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 237 "dtc-lexer.l" --{ return DT_AND; }; -+#line 253 "" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 238 "dtc-lexer.l" --{ return DT_OR; }; -+#line 254 "" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 240 "dtc-lexer.l" -+#line 255 "" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 257 "" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1230,12 +1239,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 255 "dtc-lexer.l" -+#line 272 "" - ECHO; - YY_BREAK --#line 1239 "dtc-lexer.lex.c" -+#line 1248 "dtc-lexer.l.c" - - case YY_END_OF_BUFFER: - { -@@ -1312,7 +1321,7 @@ ECHO; - { - (yy_did_buffer_switch_on_eof) = 0; - -- if ( yywrap( ) ) -+ if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up -@@ -1377,9 +1386,9 @@ ECHO; - */ - static int yy_get_next_buffer (void) - { -- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -- register char *source = (yytext_ptr); -- register int number_to_move, i; -+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -+ char *source = (yytext_ptr); -+ int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) -@@ -1408,7 +1417,7 @@ static int yy_get_next_buffer (void) - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ -- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; -+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); -@@ -1421,7 +1430,7 @@ static int yy_get_next_buffer (void) - - else - { -- yy_size_t num_to_read = -+ int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) -@@ -1435,7 +1444,7 @@ static int yy_get_next_buffer (void) - - if ( b->yy_is_our_buffer ) - { -- yy_size_t new_size = b->yy_buf_size * 2; -+ int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1444,11 +1453,12 @@ static int yy_get_next_buffer (void) - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ -- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); -+ yyrealloc( (void *) b->yy_ch_buf, -+ (yy_size_t) (b->yy_buf_size + 2) ); - } - else - /* Can't grow it, we don't own it. */ -- b->yy_ch_buf = 0; -+ b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( -@@ -1476,7 +1486,7 @@ static int yy_get_next_buffer (void) - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; -- yyrestart(yyin ); -+ yyrestart( yyin ); - } - - else -@@ -1490,12 +1500,15 @@ static int yy_get_next_buffer (void) - else - ret_val = EOB_ACT_CONTINUE_SCAN; - -- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { -+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ -- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); -+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( -+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); -+ /* "- 2" to take care of EOB's */ -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); - } - - (yy_n_chars) += number_to_move; -@@ -1511,15 +1524,15 @@ static int yy_get_next_buffer (void) - - static yy_state_type yy_get_previous_state (void) - { -- register yy_state_type yy_current_state; -- register char *yy_cp; -+ yy_state_type yy_current_state; -+ char *yy_cp; - - yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { -- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); -+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1528,10 +1541,10 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -+ if ( yy_current_state >= 166 ) -+ yy_c = yy_meta[yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - } - - return yy_current_state; -@@ -1544,10 +1557,10 @@ static int yy_get_next_buffer (void) - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) - { -- register int yy_is_jam; -- register char *yy_cp = (yy_c_buf_p); -+ int yy_is_jam; -+ char *yy_cp = (yy_c_buf_p); - -- register YY_CHAR yy_c = 1; -+ YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1556,15 +1569,19 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -+ if ( yy_current_state >= 166 ) -+ yy_c = yy_meta[yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 158); -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; -+ yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; - } - -+#ifndef YY_NO_UNPUT -+ -+#endif -+ - #ifndef YY_NO_INPUT - #ifdef __cplusplus - static int yyinput (void) -@@ -1589,7 +1606,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); -+ int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1606,14 +1623,14 @@ static int yy_get_next_buffer (void) - */ - - /* Reset buffer status. */ -- yyrestart(yyin ); -+ yyrestart( yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { -- if ( yywrap( ) ) -- return EOF; -+ if ( yywrap( ) ) -+ return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -@@ -1652,11 +1669,11 @@ static int yy_get_next_buffer (void) - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = -- yy_create_buffer(yyin,YY_BUF_SIZE ); -+ yy_create_buffer( yyin, YY_BUF_SIZE ); - } - -- yy_init_buffer(YY_CURRENT_BUFFER,input_file ); -- yy_load_buffer_state( ); -+ yy_init_buffer( YY_CURRENT_BUFFER, input_file ); -+ yy_load_buffer_state( ); - } - - /** Switch to a different input buffer. -@@ -1684,7 +1701,7 @@ static int yy_get_next_buffer (void) - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; -- yy_load_buffer_state( ); -+ yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag -@@ -1712,7 +1729,7 @@ static void yy_load_buffer_state (void) - { - YY_BUFFER_STATE b; - -- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - -@@ -1721,13 +1738,13 @@ static void yy_load_buffer_state (void) - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ -- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); -+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - -- yy_init_buffer(b,file ); -+ yy_init_buffer( b, file ); - - return b; - } -@@ -1746,9 +1763,9 @@ static void yy_load_buffer_state (void) - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) -- yyfree((void *) b->yy_ch_buf ); -+ yyfree( (void *) b->yy_ch_buf ); - -- yyfree((void *) b ); -+ yyfree( (void *) b ); - } - - /* Initializes or reinitializes a buffer. -@@ -1760,7 +1777,7 @@ static void yy_load_buffer_state (void) - { - int oerrno = errno; - -- yy_flush_buffer(b ); -+ yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; -@@ -1803,7 +1820,7 @@ static void yy_load_buffer_state (void) - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) -- yy_load_buffer_state( ); -+ yy_load_buffer_state( ); - } - - /** Pushes the new state onto the stack. The new state becomes -@@ -1834,7 +1851,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ -- yy_load_buffer_state( ); -+ yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } - -@@ -1853,7 +1870,7 @@ void yypop_buffer_state (void) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { -- yy_load_buffer_state( ); -+ yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } - } -@@ -1871,15 +1888,15 @@ static void yyensure_buffer_stack (void) - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ -- num_to_alloc = 1; -+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -- -+ - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -- -+ - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; -@@ -1888,7 +1905,7 @@ static void yyensure_buffer_stack (void) - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ -- int grow_size = 8 /* arbitrary grow size */; -+ yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -@@ -1908,7 +1925,7 @@ static void yyensure_buffer_stack (void) - * @param base the character buffer - * @param size the size in bytes of the character buffer - * -- * @return the newly allocated buffer state object. -+ * @return the newly allocated buffer state object. - */ - YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - { -@@ -1918,23 +1935,23 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ -- return 0; -+ return NULL; - -- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - -- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ -+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; -- b->yy_input_file = 0; -+ b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - -- yy_switch_to_buffer(b ); -+ yy_switch_to_buffer( b ); - - return b; - } -@@ -1947,10 +1964,10 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ --YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -+YY_BUFFER_STATE yy_scan_string (const char * yystr ) - { - -- return yy_scan_bytes(yystr,strlen(yystr) ); -+ return yy_scan_bytes( yystr, (int) strlen(yystr) ); - } - - /** Setup the input buffer state to scan the given bytes. The next call to yylex() will -@@ -1960,16 +1977,16 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- yy_size_t i; -+ int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ -- n = _yybytes_len + 2; -- buf = (char *) yyalloc(n ); -+ n = (yy_size_t) (_yybytes_len + 2); -+ buf = (char *) yyalloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - -@@ -1978,7 +1995,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - -- b = yy_scan_buffer(buf,n ); -+ b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - -@@ -1994,9 +2011,9 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len - #define YY_EXIT_FAILURE 2 - #endif - --static void yy_fatal_error (yyconst char* msg ) -+static void yynoreturn yy_fatal_error (const char* msg ) - { -- (void) fprintf( stderr, "%s\n", msg ); -+ fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - -@@ -2024,7 +2041,7 @@ static void yy_fatal_error (yyconst char* msg ) - */ - int yyget_lineno (void) - { -- -+ - return yylineno; - } - -@@ -2047,7 +2064,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --yy_size_t yyget_leng (void) -+int yyget_leng (void) - { - return yyleng; - } -@@ -2062,29 +2079,29 @@ char *yyget_text (void) - } - - /** Set the current line number. -- * @param line_number -+ * @param _line_number line number - * - */ --void yyset_lineno (int line_number ) -+void yyset_lineno (int _line_number ) - { - -- yylineno = line_number; -+ yylineno = _line_number; - } - - /** Set the input stream. This does not discard the current - * input buffer. -- * @param in_str A readable stream. -+ * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ --void yyset_in (FILE * in_str ) -+void yyset_in (FILE * _in_str ) - { -- yyin = in_str ; -+ yyin = _in_str ; - } - --void yyset_out (FILE * out_str ) -+void yyset_out (FILE * _out_str ) - { -- yyout = out_str ; -+ yyout = _out_str ; - } - - int yyget_debug (void) -@@ -2092,9 +2109,9 @@ int yyget_debug (void) - return yy_flex_debug; - } - --void yyset_debug (int bdebug ) -+void yyset_debug (int _bdebug ) - { -- yy_flex_debug = bdebug ; -+ yy_flex_debug = _bdebug ; - } - - static int yy_init_globals (void) -@@ -2103,10 +2120,10 @@ static int yy_init_globals (void) - * This function is called from yylex_destroy(), so don't allocate here. - */ - -- (yy_buffer_stack) = 0; -+ (yy_buffer_stack) = NULL; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; -- (yy_c_buf_p) = (char *) 0; -+ (yy_c_buf_p) = NULL; - (yy_init) = 0; - (yy_start) = 0; - -@@ -2115,8 +2132,8 @@ static int yy_init_globals (void) - yyin = stdin; - yyout = stdout; - #else -- yyin = (FILE *) 0; -- yyout = (FILE *) 0; -+ yyin = NULL; -+ yyout = NULL; - #endif - - /* For future reference: Set errno on error, since we are called by -@@ -2131,7 +2148,7 @@ int yylex_destroy (void) - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ -- yy_delete_buffer(YY_CURRENT_BUFFER ); -+ yy_delete_buffer( YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } -@@ -2152,18 +2169,19 @@ int yylex_destroy (void) - */ - - #ifndef yytext_ptr --static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -+static void yy_flex_strncpy (char* s1, const char * s2, int n ) - { -- register int i; -+ -+ int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } - #endif - - #ifdef YY_NEED_STRLEN --static int yy_flex_strlen (yyconst char * s ) -+static int yy_flex_strlen (const char * s ) - { -- register int n; -+ int n; - for ( n = 0; s[n]; ++n ) - ; - -@@ -2173,11 +2191,12 @@ static int yy_flex_strlen (yyconst char * s ) - - void *yyalloc (yy_size_t size ) - { -- return (void *) malloc( size ); -+ return malloc(size); - } - - void *yyrealloc (void * ptr, yy_size_t size ) - { -+ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter -@@ -2185,18 +2204,17 @@ void *yyrealloc (void * ptr, yy_size_t size ) - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ -- return (void *) realloc( (char *) ptr, size ); -+ return realloc(ptr, size); - } - - void yyfree (void * ptr ) - { -- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ - } - - #define YYTABLES_NAME "yytables" - --#line 254 "dtc-lexer.l" -- -+#line 272 "" - - - static void push_input_file(const char *filename) -@@ -2207,7 +2225,7 @@ static void push_input_file(const char *filename) - - yyin = current_srcfile->f; - -- yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); -+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); - } - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 27fac4b9c..06a6e9414 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison implementation for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "3.0.2" -+#define YYBISON_VERSION "3.0.4" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -65,6 +65,7 @@ - #line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -77,10 +78,10 @@ extern void yyerror(char const *s); - treesource_error = true; \ - } while (0) - --extern struct boot_info *the_boot_info; -+extern struct dt_info *parser_output; - extern bool treesource_error; - --#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ -+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - - # ifndef YY_NULLPTR - # if defined __cplusplus && 201103L <= __cplusplus -@@ -116,35 +117,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:355 */ -+#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; -@@ -162,9 +164,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - --#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ -+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -@@ -192,7 +197,7 @@ int yyparse (void); - - /* Copy the second part of user declarations. */ - --#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ -+#line 201 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -434,23 +439,23 @@ union yyalloc - #endif /* !YYCOPY_NEEDED */ - - /* YYFINAL -- State number of the termination state. */ --#define YYFINAL 4 -+#define YYFINAL 6 - /* YYLAST -- Last index in YYTABLE. */ --#define YYLAST 133 -+#define YYLAST 140 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 47 -+#define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 30 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 79 -+#define YYNRULES 85 - /* YYNSTATES -- Number of states. */ --#define YYNSTATES 141 -+#define YYNSTATES 151 - - /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 278 -+#define YYMAXUTOK 279 - - #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -@@ -462,16 +467,16 @@ static const yytype_uint8 yytranslate[] = - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, -+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, -+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -486,21 +491,22 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - }; - - #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 104, 104, 113, 116, 123, 127, 135, 139, 143, -- 153, 168, 176, 179, 186, 190, 194, 198, 206, 210, -- 214, 218, 222, 238, 248, 256, 259, 263, 270, 286, -- 291, 310, 324, 331, 332, 333, 340, 344, 345, 349, -- 350, 354, 355, 359, 360, 364, 365, 369, 370, 374, -- 375, 376, 380, 381, 382, 383, 384, 388, 389, 390, -- 394, 395, 396, 400, 401, 402, 403, 407, 408, 409, -- 410, 415, 418, 422, 430, 433, 437, 445, 449, 453 -+ 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, -+ 153, 161, 165, 169, 180, 191, 210, 225, 233, 236, -+ 243, 247, 251, 255, 263, 267, 271, 275, 279, 295, -+ 305, 313, 316, 320, 327, 343, 348, 367, 381, 388, -+ 389, 390, 397, 401, 402, 406, 407, 411, 412, 416, -+ 417, 421, 422, 426, 427, 431, 432, 433, 437, 438, -+ 439, 440, 441, 445, 446, 447, 451, 452, 453, 457, -+ 458, 467, 476, 480, 481, 482, 483, 488, 491, 495, -+ 503, 506, 510, 518, 522, 526 - }; - #endif - -@@ -509,19 +515,20 @@ static const yytype_uint16 yyrline[] = - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "header", "headers", "memreserves", "memreserve", "devicetree", -+ "nodedef", "proplist", "propdef", "propdata", "propdataprefix", -+ "arrayprefix", "integer_prim", "integer_expr", "integer_trinary", -+ "integer_or", "integer_and", "integer_bitor", "integer_bitxor", -+ "integer_bitand", "integer_eq", "integer_rela", "integer_shift", -+ "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes", -+ "subnode", YY_NULLPTR - }; - #endif - -@@ -532,16 +539,16 @@ static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -- 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -+ 94, 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --#define YYPACT_NINF -38 -+#define YYPACT_NINF -81 - - #define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-38))) -+ (!!((Yystate) == (-81))) - - #define YYTABLE_NINF -1 - -@@ -552,21 +559,22 @@ static const yytype_uint16 yytoknum[] = - STATE-NUM. */ - static const yytype_int8 yypact[] = - { -- 21, 11, 45, 10, -38, 9, 10, 15, 10, -38, -- -38, -9, 9, -38, 56, 40, -38, -9, -9, -9, -- -38, 51, -38, -6, 75, 49, 52, 48, 50, 3, -- 66, 33, 0, -38, 65, -38, -38, 68, 56, 56, -- -38, -38, -38, -38, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -38, 42, 69, -38, -38, 75, 55, -- 49, 52, 48, 50, 3, 3, 66, 66, 66, 66, -- 33, 33, 0, 0, -38, -38, -38, 78, 79, -11, -- 42, -38, 70, 42, -38, -9, 72, 74, -38, -38, -- -38, -38, -38, 76, -38, -38, -38, -38, -38, 18, -- -1, -38, -38, -38, -38, 82, -38, -38, -38, 71, -- -38, -38, 32, 67, 81, -3, -38, -38, -38, -38, -- -38, 43, -38, -38, -38, 9, -38, 73, 9, 77, -- -38 -+ 11, 17, 23, 11, 10, 56, -81, -81, 21, 10, -+ -5, 10, 39, -81, -81, -13, 21, -81, 44, 44, -+ 43, -81, -81, -13, -13, -13, -81, 38, -81, -2, -+ 67, 53, 55, 57, 41, 1, 75, 42, -19, -81, -+ 58, -81, -81, -81, 73, 74, 44, 44, -81, -81, -+ -81, -81, -13, -13, -13, -13, -13, -13, -13, -13, -+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -+ -13, -81, 46, 76, 44, -81, -81, 67, 61, 53, -+ 55, 57, 41, 1, 1, 75, 75, 75, 75, 42, -+ 42, -19, -19, -81, -81, -81, 83, 85, 45, 46, -+ -81, 77, 46, -81, -81, -13, 78, 79, -81, -81, -+ -81, -81, -81, 81, -81, -81, -81, -81, -81, 16, -+ 22, -81, -81, -81, -81, 89, -81, -81, -81, 80, -+ -81, -81, -6, 72, 88, 35, -81, -81, -81, -81, -+ -81, 52, -81, -81, -81, 21, -81, 82, 21, 84, -+ -81 - }; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -@@ -574,37 +582,38 @@ static const yytype_int8 yypact[] = - means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 33, -- 34, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 67, 0, 36, 37, 39, 41, 43, 45, 47, 49, -- 52, 59, 62, 66, 0, 12, 7, 0, 0, 0, -- 68, 69, 70, 35, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, -+ 0, 7, 0, 39, 40, 0, 0, 10, 0, 0, -+ 2, 8, 4, 0, 0, 0, 73, 0, 42, 43, -+ 45, 47, 49, 51, 53, 55, 58, 65, 68, 72, -+ 0, 18, 13, 11, 0, 0, 0, 0, 74, 75, -+ 76, 41, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 5, 74, 0, 9, 8, 40, 0, -- 42, 44, 46, 48, 50, 51, 55, 56, 54, 53, -- 57, 58, 60, 61, 64, 63, 65, 0, 0, 0, -- 0, 13, 0, 74, 10, 0, 0, 0, 15, 25, -- 77, 17, 79, 0, 76, 75, 38, 16, 78, 0, -- 0, 11, 24, 14, 26, 0, 18, 27, 21, 0, -- 71, 29, 0, 0, 0, 0, 32, 31, 19, 30, -- 28, 0, 72, 73, 20, 0, 23, 0, 0, 0, -- 22 -+ 0, 9, 80, 0, 0, 15, 12, 46, 0, 48, -+ 50, 52, 54, 56, 57, 61, 62, 60, 59, 63, -+ 64, 66, 67, 70, 69, 71, 0, 0, 0, 0, -+ 19, 0, 80, 16, 14, 0, 0, 0, 21, 31, -+ 83, 23, 85, 0, 82, 81, 44, 22, 84, 0, -+ 0, 17, 30, 20, 32, 0, 24, 33, 27, 0, -+ 77, 35, 0, 0, 0, 0, 38, 37, 25, 36, -+ 34, 0, 78, 79, 26, 0, 29, 0, 0, 0, -+ 28 - }; - - /* YYPGOTO[NTERM-NUM]. */ - static const yytype_int8 yypgoto[] = - { -- -38, -38, 96, 99, -38, -37, -38, -20, -38, -38, -- -38, -5, 62, 13, -38, 80, 63, 84, 64, 61, -- 28, 14, 24, 25, -14, -38, 20, 26 -+ -81, -81, -81, 107, 100, 103, -81, -18, -81, -80, -+ -81, -81, -81, -8, 62, 9, -81, 65, 64, 66, -+ 69, 63, 30, 15, 26, 27, -21, -81, 20, 24 - }; - - /* YYDEFGOTO[NTERM-NUM]. */ --static const yytype_int8 yydefgoto[] = -+static const yytype_int16 yydefgoto[] = - { -- -1, 2, 7, 8, 15, 36, 64, 91, 109, 110, -- 122, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 125, 92, 93 -+ -1, 2, 3, 4, 10, 11, 20, 42, 72, 100, -+ 119, 120, 132, 26, 27, 28, 29, 30, 31, 32, -+ 33, 34, 35, 36, 37, 38, 39, 135, 101, 102 - }; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -@@ -612,85 +621,90 @@ static const yytype_int8 yydefgoto[] = - number is the opposite. If YYTABLE_NINF, syntax error. */ - static const yytype_uint8 yytable[] = - { -- 12, 66, 67, 40, 41, 42, 44, 34, 9, 10, -- 52, 53, 115, 98, 5, 35, 132, 99, 133, 116, -- 117, 118, 119, 11, 1, 60, 9, 10, 134, 120, -- 45, 6, 54, 17, 121, 3, 18, 19, 55, 112, -- 14, 11, 113, 61, 62, 4, 84, 85, 86, 9, -- 10, 114, 100, 126, 127, 37, 87, 88, 89, 50, -- 51, 128, 38, 90, 11, 39, 76, 77, 78, 79, -- 101, 56, 57, 104, 58, 59, 135, 136, 74, 75, -- 80, 81, 35, 82, 83, 43, 46, 47, 49, 63, -- 65, 48, 95, 94, 96, 97, 107, 103, 108, 123, -- 111, 131, 130, 124, 16, 13, 138, 69, 106, 70, -- 73, 140, 72, 105, 0, 0, 102, 129, 0, 0, -- 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, -- 137, 71, 0, 139 -+ 16, 43, 48, 49, 50, 13, 14, 68, 40, 60, -+ 61, 52, 13, 14, 1, 8, 136, 137, 18, 111, -+ 15, 19, 114, 6, 138, 69, 70, 15, 75, 76, -+ 23, 62, 9, 24, 25, 53, 125, 63, 122, 13, -+ 14, 123, 5, 126, 127, 128, 129, 93, 94, 95, -+ 124, 58, 59, 130, 15, 142, 104, 143, 131, 44, -+ 12, 96, 97, 98, 22, 45, 46, 144, 99, 47, -+ 108, 41, 41, 51, 109, 85, 86, 87, 88, 54, -+ 110, 64, 65, 71, 66, 67, 145, 146, 83, 84, -+ 89, 90, 55, 91, 92, 56, 73, 74, 57, 105, -+ 106, 103, 107, 117, 118, 113, 121, 133, 140, 141, -+ 7, 21, 17, 134, 116, 78, 148, 77, 79, 150, -+ 82, 80, 115, 112, 139, 81, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, -+ 149 - }; - - static const yytype_int16 yycheck[] = - { -- 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 13, 24, 4, 26, 19, 28, 21, 20, -- 21, 22, 23, 32, 3, 25, 17, 18, 31, 30, -- 36, 21, 29, 42, 35, 24, 45, 46, 35, 21, -- 25, 32, 24, 43, 44, 0, 60, 61, 62, 17, -- 18, 33, 89, 21, 22, 15, 14, 15, 16, 9, -- 10, 29, 22, 21, 32, 25, 52, 53, 54, 55, -- 90, 5, 6, 93, 41, 42, 33, 34, 50, 51, -- 56, 57, 26, 58, 59, 34, 11, 38, 40, 24, -- 22, 39, 37, 24, 16, 16, 24, 27, 24, 17, -- 24, 20, 35, 32, 8, 6, 33, 45, 95, 46, -- 49, 34, 48, 93, -1, -1, 90, 122, -1, -1, -- -1, -1, -1, -1, 44, -1, -1, -1, -1, -1, -- 135, 47, -1, 138 -+ 8, 19, 23, 24, 25, 18, 19, 26, 16, 8, -+ 9, 13, 18, 19, 3, 5, 22, 23, 23, 99, -+ 33, 26, 102, 0, 30, 44, 45, 33, 46, 47, -+ 43, 30, 22, 46, 47, 37, 14, 36, 22, 18, -+ 19, 25, 25, 21, 22, 23, 24, 68, 69, 70, -+ 34, 10, 11, 31, 33, 20, 74, 22, 36, 16, -+ 4, 15, 16, 17, 25, 22, 23, 32, 22, 26, -+ 25, 27, 27, 35, 29, 60, 61, 62, 63, 12, -+ 98, 6, 7, 25, 42, 43, 34, 35, 58, 59, -+ 64, 65, 39, 66, 67, 40, 23, 23, 41, 38, -+ 17, 25, 17, 25, 25, 28, 25, 18, 36, 21, -+ 3, 11, 9, 33, 105, 53, 34, 52, 54, 35, -+ 57, 55, 102, 99, 132, 56, -1, -1, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, 145, -1, -1, -+ 148 - }; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ - static const yytype_uint8 yystos[] = - { -- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -- 68, 69, 70, 71, 58, 26, 52, 15, 22, 25, -- 71, 71, 71, 34, 12, 36, 11, 38, 39, 40, -- 9, 10, 7, 8, 29, 35, 5, 6, 41, 42, -- 25, 43, 44, 24, 53, 22, 52, 52, 62, 59, -- 63, 64, 65, 66, 67, 67, 68, 68, 68, 68, -- 69, 69, 70, 70, 71, 71, 71, 14, 15, 16, -- 21, 54, 73, 74, 24, 37, 16, 16, 24, 28, -- 52, 54, 74, 27, 54, 73, 60, 24, 24, 55, -- 56, 24, 21, 24, 33, 13, 20, 21, 22, 23, -- 30, 35, 57, 17, 32, 72, 21, 22, 29, 58, -- 35, 20, 19, 21, 31, 33, 34, 58, 33, 58, -- 34 -+ 0, 3, 49, 50, 51, 25, 0, 51, 5, 22, -+ 52, 53, 4, 18, 19, 33, 61, 53, 23, 26, -+ 54, 52, 25, 43, 46, 47, 61, 62, 63, 64, -+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -+ 61, 27, 55, 55, 16, 22, 23, 26, 74, 74, -+ 74, 35, 13, 37, 12, 39, 40, 41, 10, 11, -+ 8, 9, 30, 36, 6, 7, 42, 43, 26, 44, -+ 45, 25, 56, 23, 23, 55, 55, 65, 62, 66, -+ 67, 68, 69, 70, 70, 71, 71, 71, 71, 72, -+ 72, 73, 73, 74, 74, 74, 15, 16, 17, 22, -+ 57, 76, 77, 25, 55, 38, 17, 17, 25, 29, -+ 55, 57, 77, 28, 57, 76, 63, 25, 25, 58, -+ 59, 25, 22, 25, 34, 14, 21, 22, 23, 24, -+ 31, 36, 60, 18, 33, 75, 22, 23, 30, 61, -+ 36, 21, 20, 22, 32, 34, 35, 61, 34, 61, -+ 35 - }; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ - static const yytype_uint8 yyr1[] = - { -- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -- 51, 52, 53, 53, 54, 54, 54, 54, 55, 55, -- 55, 55, 55, 55, 55, 56, 56, 56, 57, 57, -- 57, 57, 57, 58, 58, 58, 59, 60, 60, 61, -- 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, -- 66, 66, 67, 67, 67, 67, 67, 68, 68, 68, -- 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, -- 71, 72, 72, 72, 73, 73, 73, 74, 74, 74 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 54, 54, 54, 54, 54, 54, 55, 56, 56, -+ 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, -+ 58, 59, 59, 59, 60, 60, 60, 60, 60, 61, -+ 61, 61, 62, 63, 63, 64, 64, 65, 65, 66, -+ 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, -+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, -+ 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, -+ 76, 76, 76, 77, 77, 77 - }; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ - static const yytype_uint8 yyr2[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 3, -- 4, 5, 0, 2, 4, 2, 3, 2, 2, 3, -- 4, 2, 9, 5, 2, 0, 2, 2, 3, 1, -- 2, 2, 2, 1, 1, 3, 1, 1, 5, 1, -- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, -- 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, -- 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, -- 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 -+ 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, -+ 2, 2, 3, 2, 4, 3, 4, 5, 0, 2, -+ 4, 2, 3, 2, 2, 3, 4, 2, 9, 5, -+ 2, 0, 2, 2, 3, 1, 2, 2, 2, 1, -+ 1, 3, 1, 1, 5, 1, 3, 1, 3, 1, -+ 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, -+ 3, 3, 3, 3, 3, 1, 3, 3, 1, 3, -+ 3, 3, 1, 1, 2, 2, 2, 0, 2, 2, -+ 0, 2, 2, 2, 3, 2 - }; - - -@@ -1460,79 +1474,144 @@ yyreduce: - switch (yyn) - { - case 2: --#line 105 "dtc-parser.y" /* yacc.c:1646 */ -+#line 110 "dtc-parser.y" /* yacc.c:1646 */ - { -- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -- guess_boot_cpuid((yyvsp[0].node))); -+ parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } --#line 1469 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1483 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --#line 113 "dtc-parser.y" /* yacc.c:1646 */ -+#line 118 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.flags) = DTSF_V1; - } --#line 1477 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1491 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --#line 117 "dtc-parser.y" /* yacc.c:1646 */ -+#line 122 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.flags) = DTSF_V1 | DTSF_PLUGIN; -+ } -+#line 1499 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 6: -+#line 130 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ if ((yyvsp[0].flags) != (yyvsp[-1].flags)) -+ ERROR(&(yylsp[0]), "Header flags don't match earlier ones"); -+ (yyval.flags) = (yyvsp[-1].flags); -+ } -+#line 1509 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 7: -+#line 139 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.re) = NULL; -+ } -+#line 1517 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 8: -+#line 143 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } --#line 1485 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1525 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 5: --#line 124 "dtc-parser.y" /* yacc.c:1646 */ -+ case 9: -+#line 150 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } --#line 1493 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1533 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 6: --#line 128 "dtc-parser.y" /* yacc.c:1646 */ -+ case 10: -+#line 154 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); - (yyval.re) = (yyvsp[0].re); - } --#line 1502 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1542 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 7: --#line 136 "dtc-parser.y" /* yacc.c:1646 */ -+ case 11: -+#line 162 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), ""); - } --#line 1510 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 8: --#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ case 12: -+#line 166 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } --#line 1518 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1558 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 9: --#line 144 "dtc-parser.y" /* yacc.c:1646 */ -+ case 13: -+#line 170 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ /* -+ * We rely on the rule being always: -+ * versioninfo plugindecl memreserves devicetree -+ * so $-1 is what we want (plugindecl) -+ */ -+ if (!((yyvsp[(-1) - (2)].flags) & DTSF_PLUGIN)) -+ ERROR(&(yylsp[0]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = add_orphan_node(name_node(build_node(NULL, NULL), ""), (yyvsp[0].node), (yyvsp[-1].labelref)); -+ } -+#line 1573 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - -- if (target) -+ case 14: -+#line 181 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ -+ if (target) { -+ add_label(&target->labels, (yyvsp[-2].labelref)); - merge_nodes(target, (yyvsp[0].node)); -- else -+ } else - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-3].node); -+ } -+#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 15: -+#line 192 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ -+ if (target) { -+ merge_nodes(target, (yyvsp[0].node)); -+ } else { -+ /* -+ * We rely on the rule being always: -+ * versioninfo plugindecl memreserves devicetree -+ * so $-1 is what we want (plugindecl) -+ */ -+ if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN) -+ add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ } - (yyval.node) = (yyvsp[-2].node); - } --#line 1532 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1611 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 10: --#line 154 "dtc-parser.y" /* yacc.c:1646 */ -+ case 16: -+#line 211 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -@@ -1544,100 +1623,100 @@ yyreduce: - - (yyval.node) = (yyvsp[-3].node); - } --#line 1548 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1627 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 11: --#line 169 "dtc-parser.y" /* yacc.c:1646 */ -+ case 17: -+#line 226 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } --#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1635 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 12: --#line 176 "dtc-parser.y" /* yacc.c:1646 */ -+ case 18: -+#line 233 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = NULL; - } --#line 1564 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1643 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 13: --#line 180 "dtc-parser.y" /* yacc.c:1646 */ -+ case 19: -+#line 237 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } --#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1651 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 14: --#line 187 "dtc-parser.y" /* yacc.c:1646 */ -+ case 20: -+#line 244 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } --#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1659 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 15: --#line 191 "dtc-parser.y" /* yacc.c:1646 */ -+ case 21: -+#line 248 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } --#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1667 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 16: --#line 195 "dtc-parser.y" /* yacc.c:1646 */ -+ case 22: -+#line 252 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } --#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 17: --#line 199 "dtc-parser.y" /* yacc.c:1646 */ -+ case 23: -+#line 256 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); - (yyval.prop) = (yyvsp[0].prop); - } --#line 1605 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1684 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 18: --#line 207 "dtc-parser.y" /* yacc.c:1646 */ -+ case 24: -+#line 264 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } --#line 1613 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1692 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 19: --#line 211 "dtc-parser.y" /* yacc.c:1646 */ -+ case 25: -+#line 268 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } --#line 1621 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1700 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 20: --#line 215 "dtc-parser.y" /* yacc.c:1646 */ -+ case 26: -+#line 272 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } --#line 1629 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1708 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 21: --#line 219 "dtc-parser.y" /* yacc.c:1646 */ -+ case 27: -+#line 276 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } --#line 1637 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1716 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 22: --#line 223 "dtc-parser.y" /* yacc.c:1646 */ -+ case 28: -+#line 280 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; -@@ -1653,11 +1732,11 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } --#line 1657 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1736 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 23: --#line 239 "dtc-parser.y" /* yacc.c:1646 */ -+ case 29: -+#line 296 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; -@@ -1667,43 +1746,43 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } --#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --#line 249 "dtc-parser.y" /* yacc.c:1646 */ -+ case 30: -+#line 306 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1758 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --#line 256 "dtc-parser.y" /* yacc.c:1646 */ -+ case 31: -+#line 313 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1766 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --#line 260 "dtc-parser.y" /* yacc.c:1646 */ -+ case 32: -+#line 317 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = (yyvsp[-1].data); - } --#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1774 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --#line 264 "dtc-parser.y" /* yacc.c:1646 */ -+ case 33: -+#line 321 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1703 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --#line 271 "dtc-parser.y" /* yacc.c:1646 */ -+ case 34: -+#line 328 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - -@@ -1719,20 +1798,20 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } --#line 1723 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1802 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --#line 287 "dtc-parser.y" /* yacc.c:1646 */ -+ case 35: -+#line 344 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } --#line 1732 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1811 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --#line 292 "dtc-parser.y" /* yacc.c:1646 */ -+ case 36: -+#line 349 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[-1].array).bits < 64) { - uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; -@@ -1751,11 +1830,11 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } --#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1834 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --#line 311 "dtc-parser.y" /* yacc.c:1646 */ -+ case 37: -+#line 368 "dtc-parser.y" /* yacc.c:1646 */ - { - uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -@@ -1769,233 +1848,247 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } --#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1852 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: --#line 325 "dtc-parser.y" /* yacc.c:1646 */ -+ case 38: -+#line 382 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } --#line 1781 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1860 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 35: --#line 334 "dtc-parser.y" /* yacc.c:1646 */ -+ case 41: -+#line 391 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.integer) = (yyvsp[-1].integer); - } --#line 1789 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1868 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 38: --#line 345 "dtc-parser.y" /* yacc.c:1646 */ -+ case 44: -+#line 402 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } --#line 1795 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1874 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 40: --#line 350 "dtc-parser.y" /* yacc.c:1646 */ -+ case 46: -+#line 407 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } --#line 1801 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1880 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 42: --#line 355 "dtc-parser.y" /* yacc.c:1646 */ -+ case 48: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } --#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1886 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 44: --#line 360 "dtc-parser.y" /* yacc.c:1646 */ -+ case 50: -+#line 417 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } --#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1892 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 46: --#line 365 "dtc-parser.y" /* yacc.c:1646 */ -+ case 52: -+#line 422 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } --#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1898 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 48: --#line 370 "dtc-parser.y" /* yacc.c:1646 */ -+ case 54: -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } --#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1904 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 50: --#line 375 "dtc-parser.y" /* yacc.c:1646 */ -+ case 56: -+#line 432 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } --#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1910 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 51: --#line 376 "dtc-parser.y" /* yacc.c:1646 */ -+ case 57: -+#line 433 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } --#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1916 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 53: --#line 381 "dtc-parser.y" /* yacc.c:1646 */ -+ case 59: -+#line 438 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } --#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 54: --#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ case 60: -+#line 439 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } --#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1928 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 55: --#line 383 "dtc-parser.y" /* yacc.c:1646 */ -+ case 61: -+#line 440 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } --#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1934 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 56: --#line 384 "dtc-parser.y" /* yacc.c:1646 */ -+ case 62: -+#line 441 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } --#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1940 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 57: --#line 388 "dtc-parser.y" /* yacc.c:1646 */ -+ case 63: -+#line 445 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } --#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1946 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 58: --#line 389 "dtc-parser.y" /* yacc.c:1646 */ -+ case 64: -+#line 446 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } --#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1952 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 60: --#line 394 "dtc-parser.y" /* yacc.c:1646 */ -+ case 66: -+#line 451 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } --#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1958 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 61: --#line 395 "dtc-parser.y" /* yacc.c:1646 */ -+ case 67: -+#line 452 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } --#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1964 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 63: --#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ case 69: -+#line 457 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } --#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1970 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 64: --#line 401 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } --#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 70: -+#line 459 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ if ((yyvsp[0].integer) != 0) { -+ (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); -+ } else { -+ ERROR(&(yyloc), "Division by zero"); -+ (yyval.integer) = 0; -+ } -+ } -+#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 65: --#line 402 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } --#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 71: -+#line 468 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ if ((yyvsp[0].integer) != 0) { -+ (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); -+ } else { -+ ERROR(&(yyloc), "Division by zero"); -+ (yyval.integer) = 0; -+ } -+ } -+#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 68: --#line 408 "dtc-parser.y" /* yacc.c:1646 */ -+ case 74: -+#line 481 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = -(yyvsp[0].integer); } --#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 69: --#line 409 "dtc-parser.y" /* yacc.c:1646 */ -+ case 75: -+#line 482 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2008 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 70: --#line 410 "dtc-parser.y" /* yacc.c:1646 */ -+ case 76: -+#line 483 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = !(yyvsp[0].integer); } --#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2014 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 71: --#line 415 "dtc-parser.y" /* yacc.c:1646 */ -+ case 77: -+#line 488 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2022 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 72: --#line 419 "dtc-parser.y" /* yacc.c:1646 */ -+ case 78: -+#line 492 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } --#line 1937 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2030 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 73: --#line 423 "dtc-parser.y" /* yacc.c:1646 */ -+ case 79: -+#line 496 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1945 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2038 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 74: --#line 430 "dtc-parser.y" /* yacc.c:1646 */ -+ case 80: -+#line 503 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = NULL; - } --#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2046 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 75: --#line 434 "dtc-parser.y" /* yacc.c:1646 */ -+ case 81: -+#line 507 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } --#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2054 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 76: --#line 438 "dtc-parser.y" /* yacc.c:1646 */ -+ case 82: -+#line 511 "dtc-parser.y" /* yacc.c:1646 */ - { - ERROR(&(yylsp[0]), "Properties must precede subnodes"); - YYERROR; - } --#line 1970 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 77: --#line 446 "dtc-parser.y" /* yacc.c:1646 */ -+ case 83: -+#line 519 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } --#line 1978 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2071 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 78: --#line 450 "dtc-parser.y" /* yacc.c:1646 */ -+ case 84: -+#line 523 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } --#line 1986 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2079 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 79: --#line 454 "dtc-parser.y" /* yacc.c:1646 */ -+ case 85: -+#line 527 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[0].node); - } --#line 1995 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2088 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - --#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2092 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2230,7 +2323,7 @@ yyreturn: - #endif - return yyresult; - } --#line 460 "dtc-parser.y" /* yacc.c:1906 */ -+#line 533 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 30867c688..6aa512c1b 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison interface for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -46,35 +46,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:1909 */ -+#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; -@@ -92,9 +93,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - --#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ -+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index ea57e0a05..44af170ab 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,6 +19,7 @@ - */ - %{ - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -31,7 +32,7 @@ extern void yyerror(char const *s); - treesource_error = true; \ - } while (0) - --extern struct boot_info *the_boot_info; -+extern struct dt_info *parser_output; - extern bool treesource_error; - %} - -@@ -52,9 +53,11 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -71,6 +74,8 @@ extern bool treesource_error; - - %type propdata - %type propdataprefix -+%type header -+%type headers - %type memreserve - %type memreserves - %type arrayprefix -@@ -101,10 +106,31 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ headers memreserves devicetree - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ parser_output = build_dt_info($1, $2, $3, -+ guess_boot_cpuid($3)); -+ } -+ ; -+ -+header: -+ DT_V1 ';' -+ { -+ $$ = DTSF_V1; -+ } -+ | DT_V1 ';' DT_PLUGIN ';' -+ { -+ $$ = DTSF_V1 | DTSF_PLUGIN; -+ } -+ ; -+ -+headers: -+ header -+ | header headers -+ { -+ if ($2 != $1) -+ ERROR(&@2, "Header flags don't match earlier ones"); -+ $$ = $1; - } - ; - -@@ -140,14 +166,45 @@ devicetree: - { - $$ = merge_nodes($1, $3); - } -+ | DT_REF nodedef -+ { -+ /* -+ * We rely on the rule being always: -+ * versioninfo plugindecl memreserves devicetree -+ * so $-1 is what we want (plugindecl) -+ */ -+ if (!($-1 & DTSF_PLUGIN)) -+ ERROR(&@2, "Label or path %s not found", $1); -+ $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); -+ } -+ | devicetree DT_LABEL DT_REF nodedef -+ { -+ struct node *target = get_node_by_ref($1, $3); -+ -+ if (target) { -+ add_label(&target->labels, $2); -+ merge_nodes(target, $4); -+ } else -+ ERROR(&@3, "Label or path %s not found", $3); -+ $$ = $1; -+ } - | devicetree DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $2); - -- if (target) -+ if (target) { - merge_nodes(target, $3); -- else -- ERROR(&@2, "Label or path %s not found", $2); -+ } else { -+ /* -+ * We rely on the rule being always: -+ * versioninfo plugindecl memreserves devicetree -+ * so $-1 is what we want (plugindecl) -+ */ -+ if ($-1 & DTSF_PLUGIN) -+ add_orphan_node($1, $3, $2); -+ else -+ ERROR(&@2, "Label or path %s not found", $2); -+ } - $$ = $1; - } - | devicetree DT_DEL_NODE DT_REF ';' -@@ -398,8 +455,24 @@ integer_add: - - integer_mul: - integer_mul '*' integer_unary { $$ = $1 * $3; } -- | integer_mul '/' integer_unary { $$ = $1 / $3; } -- | integer_mul '%' integer_unary { $$ = $1 % $3; } -+ | integer_mul '/' integer_unary -+ { -+ if ($3 != 0) { -+ $$ = $1 / $3; -+ } else { -+ ERROR(&@$, "Division by zero"); -+ $$ = 0; -+ } -+ } -+ | integer_mul '%' integer_unary -+ { -+ if ($3 != 0) { -+ $$ = $1 % $3; -+ } else { -+ ERROR(&@$, "Division by zero"); -+ $$ = 0; -+ } -+ } - | integer_unary - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 8c4add69a..c36994e6e 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -18,6 +18,8 @@ - * USA - */ - -+#include -+ - #include "dtc.h" - #include "srcpos.h" - -@@ -28,7 +30,16 @@ int quiet; /* Level of quietness */ - int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ --int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int alignsize; /* Additional padding to blob accroding to the alignsize */ -+int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */ -+int generate_symbols; /* enable symbols & fixup support */ -+int generate_fixups; /* suppress generation of fixups on symbol support */ -+int auto_label_aliases; /* auto generate labels -> aliases */ -+ -+static int is_power_of_2(int x) -+{ -+ return (x > 0) && ((x & (x - 1)) == 0); -+} - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -48,10 +59,8 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - } - - /* Usage related data. */ --#define FDT_VERSION(version) _FDT_VERSION(version) --#define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -62,6 +71,7 @@ static struct option const usage_long_opts[] = { - {"reserve", a_argument, NULL, 'R'}, - {"space", a_argument, NULL, 'S'}, - {"pad", a_argument, NULL, 'p'}, -+ {"align", a_argument, NULL, 'a'}, - {"boot-cpu", a_argument, NULL, 'b'}, - {"force", no_argument, NULL, 'f'}, - {"include", a_argument, NULL, 'i'}, -@@ -69,6 +79,8 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", no_argument, NULL, '@'}, -+ {"auto-alias", no_argument, NULL, 'A'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -84,11 +96,12 @@ static const char * const usage_opts_help[] = { - "\t\tdts - device tree source text\n" - "\t\tdtb - device tree blob\n" - "\t\tasm - assembler source", -- "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", -+ "\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)", - "\n\tOutput dependency file", - "\n\tMake space for reserve map entries (for dtb and asm output)", - "\n\tMake the blob at least long (extra space)", - "\n\tAdd padding to the blob of long (extra space)", -+ "\n\tMake the blob align to the (extra space)", - "\n\tSet the physical boot cpu", - "\n\tTry to produce output even if the input tree has errors", - "\n\tAdd a path to search for include files", -@@ -99,16 +112,62 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tEnable generation of symbols", -+ "\n\tEnable auto-alias of labels", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, - }; - -+static const char *guess_type_by_name(const char *fname, const char *fallback) -+{ -+ const char *s; -+ -+ s = strrchr(fname, '.'); -+ if (s == NULL) -+ return fallback; -+ if (!strcasecmp(s, ".dts")) -+ return "dts"; -+ if (!strcasecmp(s, ".dtb")) -+ return "dtb"; -+ return fallback; -+} -+ -+static const char *guess_input_format(const char *fname, const char *fallback) -+{ -+ struct stat statbuf; -+ fdt32_t magic; -+ FILE *f; -+ -+ if (stat(fname, &statbuf) != 0) -+ return fallback; -+ -+ if (S_ISDIR(statbuf.st_mode)) -+ return "fs"; -+ -+ if (!S_ISREG(statbuf.st_mode)) -+ return fallback; -+ -+ f = fopen(fname, "r"); -+ if (f == NULL) -+ return fallback; -+ if (fread(&magic, 4, 1, f) != 1) { -+ fclose(f); -+ return fallback; -+ } -+ fclose(f); -+ -+ if (fdt32_to_cpu(magic) == FDT_MAGIC) -+ return "dtb"; -+ -+ return guess_type_by_name(fname, fallback); -+} -+ - int main(int argc, char *argv[]) - { -- struct boot_info *bi; -- const char *inform = "dts"; -- const char *outform = "dts"; -+ struct dt_info *dti; -+ const char *inform = NULL; -+ const char *outform = NULL; - const char *outname = "-"; - const char *depname = NULL; - bool force = false, sort = false; -@@ -122,6 +181,7 @@ int main(int argc, char *argv[]) - reservenum = 0; - minsize = 0; - padsize = 0; -+ alignsize = 0; - - while ((opt = util_getopt_long()) != EOF) { - switch (opt) { -@@ -149,6 +209,12 @@ int main(int argc, char *argv[]) - case 'p': - padsize = strtol(optarg, NULL, 0); - break; -+ case 'a': -+ alignsize = strtol(optarg, NULL, 0); -+ if (!is_power_of_2(alignsize)) -+ die("Invalid argument \"%d\" to -a option\n", -+ alignsize); -+ break; - case 'f': - force = true; - break; -@@ -187,6 +253,13 @@ int main(int argc, char *argv[]) - parse_checks_option(false, true, optarg); - break; - -+ case '@': -+ generate_symbols = 1; -+ break; -+ case 'A': -+ auto_label_aliases = 1; -+ break; -+ - case 'h': - usage(NULL); - default: -@@ -213,28 +286,58 @@ int main(int argc, char *argv[]) - fprintf(depfile, "%s:", outname); - } - -+ if (inform == NULL) -+ inform = guess_input_format(arg, "dts"); -+ if (outform == NULL) { -+ outform = guess_type_by_name(outname, NULL); -+ if (outform == NULL) { -+ if (streq(inform, "dts")) -+ outform = "dtb"; -+ else -+ outform = "dts"; -+ } -+ } - if (streq(inform, "dts")) -- bi = dt_from_source(arg); -+ dti = dt_from_source(arg); - else if (streq(inform, "fs")) -- bi = dt_from_fs(arg); -+ dti = dt_from_fs(arg); - else if(streq(inform, "dtb")) -- bi = dt_from_blob(arg); -+ dti = dt_from_blob(arg); - else - die("Unknown input format \"%s\"\n", inform); - -+ dti->outname = outname; -+ - if (depfile) { - fputc('\n', depfile); - fclose(depfile); - } - - if (cmdline_boot_cpuid != -1) -- bi->boot_cpuid_phys = cmdline_boot_cpuid; -+ dti->boot_cpuid_phys = cmdline_boot_cpuid; -+ -+ fill_fullpaths(dti->dt, ""); -+ -+ /* on a plugin, generate by default */ -+ if (dti->dtsflags & DTSF_PLUGIN) { -+ generate_fixups = 1; -+ } - -- fill_fullpaths(bi->dt, ""); -- process_checks(force, bi); -+ process_checks(force, dti); -+ -+ if (auto_label_aliases) -+ generate_label_tree(dti, "aliases", false); -+ -+ if (generate_symbols) -+ generate_label_tree(dti, "__symbols__", true); -+ -+ if (generate_fixups) { -+ generate_fixups_tree(dti, "__fixups__"); -+ generate_local_fixups_tree(dti, "__local_fixups__"); -+ } - - if (sort) -- sort_tree(bi); -+ sort_tree(dti); - - if (streq(outname, "-")) { - outf = stdout; -@@ -246,11 +349,11 @@ int main(int argc, char *argv[]) - } - - if (streq(outform, "dts")) { -- dt_to_source(outf, bi); -+ dt_to_source(outf, dti); - } else if (streq(outform, "dtb")) { -- dt_to_blob(outf, bi, outversion); -+ dt_to_blob(outf, dti, outversion); - } else if (streq(outform, "asm")) { -- dt_to_asm(outf, bi, outversion); -+ dt_to_asm(outf, dti, outversion); - } else if (streq(outform, "null")) { - /* do nothing */ - } else { -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 56212c8df..3b18a42b8 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -1,5 +1,5 @@ --#ifndef _DTC_H --#define _DTC_H -+#ifndef DTC_H -+#define DTC_H - - /* - * (C) Copyright David Gibson , IBM Corporation. 2005. -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -43,7 +44,6 @@ - #define debug(...) - #endif - -- - #define DEFAULT_FDT_VERSION 17 - - /* -@@ -53,7 +53,11 @@ extern int quiet; /* Level of quietness */ - extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ -+extern int alignsize; /* Additional padding to blob accroding to the alignsize */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int generate_symbols; /* generate symbols for nodes with labels */ -+extern int generate_fixups; /* generate fixups */ -+extern int auto_label_aliases; /* auto generate labels -> aliases */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -63,7 +67,8 @@ typedef uint32_t cell_t; - - - #define streq(a, b) (strcmp((a), (b)) == 0) --#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) -+#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) -+#define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0)) - - #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) - -@@ -110,7 +115,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, - struct data data_merge(struct data d1, struct data d2); - struct data data_append_cell(struct data d, cell_t word); - struct data data_append_integer(struct data d, uint64_t word, int bits); --struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); -+struct data data_append_re(struct data d, uint64_t address, uint64_t size); - struct data data_append_addr(struct data d, uint64_t addr); - struct data data_append_byte(struct data d, uint8_t byte); - struct data data_append_zeroes(struct data d, int len); -@@ -132,6 +137,10 @@ struct label { - struct label *next; - }; - -+struct bus_type { -+ const char *name; -+}; -+ - struct property { - bool deleted; - char *name; -@@ -158,6 +167,7 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ const struct bus_type *bus; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -194,6 +204,7 @@ struct node *build_node_delete(void); - struct node *name_node(struct node *node, char *name); - struct node *chain_node(struct node *first, struct node *list); - struct node *merge_nodes(struct node *old_node, struct node *new_node); -+struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref); - - void add_property(struct node *node, struct property *prop); - void delete_property_by_name(struct node *node, char *name); -@@ -201,10 +212,13 @@ void delete_property(struct property *prop); - void add_child(struct node *parent, struct node *child); - void delete_node_by_name(struct node *parent, char *name); - void delete_node(struct node *node); -+void append_to_property(struct node *node, -+ char *name, const void *data, int len); - - const char *get_unitname(struct node *node); - struct property *get_property(struct node *node, const char *propname); - cell_t propval_cell(struct property *prop); -+cell_t propval_cell_n(struct property *prop, int n); - struct property *get_property_by_label(struct node *tree, const char *label, - struct node **node); - struct marker *get_marker_label(struct node *tree, const char *label, -@@ -221,7 +235,7 @@ uint32_t guess_boot_cpuid(struct node *tree); - /* Boot info (tree plus memreserve information */ - - struct reserve_info { -- struct fdt_reserve_entry re; -+ uint64_t address, size; - - struct reserve_info *next; - -@@ -235,35 +249,45 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, - struct reserve_info *new); - - --struct boot_info { -+struct dt_info { -+ unsigned int dtsflags; - struct reserve_info *reservelist; -- struct node *dt; /* the device tree */ - uint32_t boot_cpuid_phys; -+ struct node *dt; /* the device tree */ -+ const char *outname; /* filename being written to, "-" for stdout */ - }; - --struct boot_info *build_boot_info(struct reserve_info *reservelist, -- struct node *tree, uint32_t boot_cpuid_phys); --void sort_tree(struct boot_info *bi); -+/* DTS version flags definitions */ -+#define DTSF_V1 0x0001 /* /dts-v1/ */ -+#define DTSF_PLUGIN 0x0002 /* /plugin/ */ -+ -+struct dt_info *build_dt_info(unsigned int dtsflags, -+ struct reserve_info *reservelist, -+ struct node *tree, uint32_t boot_cpuid_phys); -+void sort_tree(struct dt_info *dti); -+void generate_label_tree(struct dt_info *dti, char *name, bool allocph); -+void generate_fixups_tree(struct dt_info *dti, char *name); -+void generate_local_fixups_tree(struct dt_info *dti, char *name); - - /* Checks */ - - void parse_checks_option(bool warn, bool error, const char *arg); --void process_checks(bool force, struct boot_info *bi); -+void process_checks(bool force, struct dt_info *dti); - - /* Flattened trees */ - --void dt_to_blob(FILE *f, struct boot_info *bi, int version); --void dt_to_asm(FILE *f, struct boot_info *bi, int version); -+void dt_to_blob(FILE *f, struct dt_info *dti, int version); -+void dt_to_asm(FILE *f, struct dt_info *dti, int version); - --struct boot_info *dt_from_blob(const char *fname); -+struct dt_info *dt_from_blob(const char *fname); - - /* Tree source */ - --void dt_to_source(FILE *f, struct boot_info *bi); --struct boot_info *dt_from_source(const char *f); -+void dt_to_source(FILE *f, struct dt_info *dti); -+struct dt_info *dt_from_source(const char *f); - - /* FS trees */ - --struct boot_info *dt_from_fs(const char *dirname); -+struct dt_info *dt_from_fs(const char *dirname); - --#endif /* _DTC_H */ -+#endif /* DTC_H */ -diff --git a/scripts/dtc/fdt.c b/scripts/dtc/fdt.c -index 2ce6a4417..7855a1787 100644 ---- a/scripts/dtc/fdt.c -+++ b/scripts/dtc/fdt.c -@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt) - - const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) - { -- const char *p; -+ unsigned absoffset = offset + fdt_off_dt_struct(fdt); -+ -+ if ((absoffset < offset) -+ || ((absoffset + len) < absoffset) -+ || (absoffset + len) > fdt_totalsize(fdt)) -+ return NULL; - - if (fdt_version(fdt) >= 0x11) - if (((offset + len) < offset) - || ((offset + len) > fdt_size_dt_struct(fdt))) - return NULL; - -- p = _fdt_offset_ptr(fdt, offset); -- -- if (p + len < p) -- return NULL; -- return p; -+ return fdt_offset_ptr_(fdt, offset); - } - - uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) -@@ -122,6 +123,9 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) - /* skip-name offset, length and value */ - offset += sizeof(struct fdt_property) - FDT_TAGSIZE - + fdt32_to_cpu(*lenp); -+ if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && -+ ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) -+ offset += 4; - break; - - case FDT_END: -@@ -140,7 +144,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) - return tag; - } - --int _fdt_check_node_offset(const void *fdt, int offset) -+int fdt_check_node_offset_(const void *fdt, int offset) - { - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) -@@ -149,7 +153,7 @@ int _fdt_check_node_offset(const void *fdt, int offset) - return offset; - } - --int _fdt_check_prop_offset(const void *fdt, int offset) -+int fdt_check_prop_offset_(const void *fdt, int offset) - { - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) -@@ -164,7 +168,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth) - uint32_t tag; - - if (offset >= 0) -- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) -+ if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) - return nextoffset; - - do { -@@ -226,7 +230,7 @@ int fdt_next_subnode(const void *fdt, int offset) - return offset; - } - --const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) -+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) - { - int len = strlen(s) + 1; - const char *last = strtab + tabsize - len; -diff --git a/scripts/dtc/fdt.h b/scripts/dtc/fdt.h -index 526aedb51..74961f902 100644 ---- a/scripts/dtc/fdt.h -+++ b/scripts/dtc/fdt.h -@@ -1,5 +1,5 @@ --#ifndef _FDT_H --#define _FDT_H -+#ifndef FDT_H -+#define FDT_H - /* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. -@@ -108,4 +108,4 @@ struct fdt_property { - #define FDT_V16_SIZE FDT_V3_SIZE - #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) - --#endif /* _FDT_H */ -+#endif /* FDT_H */ -diff --git a/scripts/dtc/fdt_empty_tree.c b/scripts/dtc/fdt_empty_tree.c -index f72d13b1d..f2ae9b77c 100644 ---- a/scripts/dtc/fdt_empty_tree.c -+++ b/scripts/dtc/fdt_empty_tree.c -@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize) - - return fdt_open_into(buf, buf, bufsize); - } -- -diff --git a/scripts/dtc/fdt_overlay.c b/scripts/dtc/fdt_overlay.c -new file mode 100644 -index 000000000..bf75388ec ---- /dev/null -+++ b/scripts/dtc/fdt_overlay.c -@@ -0,0 +1,912 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2016 Free Electrons -+ * Copyright (C) 2016 NextThing Co. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) Redistribution and use in source and binary forms, with or -+ * without modification, are permitted provided that the following -+ * conditions are met: -+ * -+ * 1. Redistributions of source code must retain the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer. -+ * 2. Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials -+ * provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+/** -+ * overlay_get_target_phandle - retrieves the target phandle of a fragment -+ * @fdto: pointer to the device tree overlay blob -+ * @fragment: node offset of the fragment in the overlay -+ * -+ * overlay_get_target_phandle() retrieves the target phandle of an -+ * overlay fragment when that fragment uses a phandle (target -+ * property) instead of a path (target-path property). -+ * -+ * returns: -+ * the phandle pointed by the target property -+ * 0, if the phandle was not found -+ * -1, if the phandle was malformed -+ */ -+static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) -+{ -+ const fdt32_t *val; -+ int len; -+ -+ val = fdt_getprop(fdto, fragment, "target", &len); -+ if (!val) -+ return 0; -+ -+ if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1)) -+ return (uint32_t)-1; -+ -+ return fdt32_to_cpu(*val); -+} -+ -+/** -+ * overlay_get_target - retrieves the offset of a fragment's target -+ * @fdt: Base device tree blob -+ * @fdto: Device tree overlay blob -+ * @fragment: node offset of the fragment in the overlay -+ * @pathp: pointer which receives the path of the target (or NULL) -+ * -+ * overlay_get_target() retrieves the target offset in the base -+ * device tree of a fragment, no matter how the actual targetting is -+ * done (through a phandle or a path) -+ * -+ * returns: -+ * the targetted node offset in the base device tree -+ * Negative error code on error -+ */ -+static int overlay_get_target(const void *fdt, const void *fdto, -+ int fragment, char const **pathp) -+{ -+ uint32_t phandle; -+ const char *path = NULL; -+ int path_len = 0, ret; -+ -+ /* Try first to do a phandle based lookup */ -+ phandle = overlay_get_target_phandle(fdto, fragment); -+ if (phandle == (uint32_t)-1) -+ return -FDT_ERR_BADPHANDLE; -+ -+ /* no phandle, try path */ -+ if (!phandle) { -+ /* And then a path based lookup */ -+ path = fdt_getprop(fdto, fragment, "target-path", &path_len); -+ if (path) -+ ret = fdt_path_offset(fdt, path); -+ else -+ ret = path_len; -+ } else -+ ret = fdt_node_offset_by_phandle(fdt, phandle); -+ -+ /* -+ * If we haven't found either a target or a -+ * target-path property in a node that contains a -+ * __overlay__ subnode (we wouldn't be called -+ * otherwise), consider it a improperly written -+ * overlay -+ */ -+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND) -+ ret = -FDT_ERR_BADOVERLAY; -+ -+ /* return on error */ -+ if (ret < 0) -+ return ret; -+ -+ /* return pointer to path (if available) */ -+ if (pathp) -+ *pathp = path ? path : NULL; -+ -+ return ret; -+} -+ -+/** -+ * overlay_phandle_add_offset - Increases a phandle by an offset -+ * @fdt: Base device tree blob -+ * @node: Device tree overlay blob -+ * @name: Name of the property to modify (phandle or linux,phandle) -+ * @delta: offset to apply -+ * -+ * overlay_phandle_add_offset() increments a node phandle by a given -+ * offset. -+ * -+ * returns: -+ * 0 on success. -+ * Negative error code on error -+ */ -+static int overlay_phandle_add_offset(void *fdt, int node, -+ const char *name, uint32_t delta) -+{ -+ const fdt32_t *val; -+ uint32_t adj_val; -+ int len; -+ -+ val = fdt_getprop(fdt, node, name, &len); -+ if (!val) -+ return len; -+ -+ if (len != sizeof(*val)) -+ return -FDT_ERR_BADPHANDLE; -+ -+ adj_val = fdt32_to_cpu(*val); -+ if ((adj_val + delta) < adj_val) -+ return -FDT_ERR_NOPHANDLES; -+ -+ adj_val += delta; -+ if (adj_val == (uint32_t)-1) -+ return -FDT_ERR_NOPHANDLES; -+ -+ return fdt_setprop_inplace_u32(fdt, node, name, adj_val); -+} -+ -+/** -+ * overlay_adjust_node_phandles - Offsets the phandles of a node -+ * @fdto: Device tree overlay blob -+ * @node: Offset of the node we want to adjust -+ * @delta: Offset to shift the phandles of -+ * -+ * overlay_adjust_node_phandles() adds a constant to all the phandles -+ * of a given node. This is mainly use as part of the overlay -+ * application process, when we want to update all the overlay -+ * phandles to not conflict with the overlays of the base device tree. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_adjust_node_phandles(void *fdto, int node, -+ uint32_t delta) -+{ -+ int child; -+ int ret; -+ -+ ret = overlay_phandle_add_offset(fdto, node, "phandle", delta); -+ if (ret && ret != -FDT_ERR_NOTFOUND) -+ return ret; -+ -+ ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta); -+ if (ret && ret != -FDT_ERR_NOTFOUND) -+ return ret; -+ -+ fdt_for_each_subnode(child, fdto, node) { -+ ret = overlay_adjust_node_phandles(fdto, child, delta); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay -+ * @fdto: Device tree overlay blob -+ * @delta: Offset to shift the phandles of -+ * -+ * overlay_adjust_local_phandles() adds a constant to all the -+ * phandles of an overlay. This is mainly use as part of the overlay -+ * application process, when we want to update all the overlay -+ * phandles to not conflict with the overlays of the base device tree. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_adjust_local_phandles(void *fdto, uint32_t delta) -+{ -+ /* -+ * Start adjusting the phandles from the overlay root -+ */ -+ return overlay_adjust_node_phandles(fdto, 0, delta); -+} -+ -+/** -+ * overlay_update_local_node_references - Adjust the overlay references -+ * @fdto: Device tree overlay blob -+ * @tree_node: Node offset of the node to operate on -+ * @fixup_node: Node offset of the matching local fixups node -+ * @delta: Offset to shift the phandles of -+ * -+ * overlay_update_local_nodes_references() update the phandles -+ * pointing to a node within the device tree overlay by adding a -+ * constant delta. -+ * -+ * This is mainly used as part of a device tree application process, -+ * where you want the device tree overlays phandles to not conflict -+ * with the ones from the base device tree before merging them. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_update_local_node_references(void *fdto, -+ int tree_node, -+ int fixup_node, -+ uint32_t delta) -+{ -+ int fixup_prop; -+ int fixup_child; -+ int ret; -+ -+ fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { -+ const fdt32_t *fixup_val; -+ const char *tree_val; -+ const char *name; -+ int fixup_len; -+ int tree_len; -+ int i; -+ -+ fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, -+ &name, &fixup_len); -+ if (!fixup_val) -+ return fixup_len; -+ -+ if (fixup_len % sizeof(uint32_t)) -+ return -FDT_ERR_BADOVERLAY; -+ -+ tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); -+ if (!tree_val) { -+ if (tree_len == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_BADOVERLAY; -+ -+ return tree_len; -+ } -+ -+ for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { -+ fdt32_t adj_val; -+ uint32_t poffset; -+ -+ poffset = fdt32_to_cpu(fixup_val[i]); -+ -+ /* -+ * phandles to fixup can be unaligned. -+ * -+ * Use a memcpy for the architectures that do -+ * not support unaligned accesses. -+ */ -+ memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); -+ -+ adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); -+ -+ ret = fdt_setprop_inplace_namelen_partial(fdto, -+ tree_node, -+ name, -+ strlen(name), -+ poffset, -+ &adj_val, -+ sizeof(adj_val)); -+ if (ret == -FDT_ERR_NOSPACE) -+ return -FDT_ERR_BADOVERLAY; -+ -+ if (ret) -+ return ret; -+ } -+ } -+ -+ fdt_for_each_subnode(fixup_child, fdto, fixup_node) { -+ const char *fixup_child_name = fdt_get_name(fdto, fixup_child, -+ NULL); -+ int tree_child; -+ -+ tree_child = fdt_subnode_offset(fdto, tree_node, -+ fixup_child_name); -+ if (tree_child == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_BADOVERLAY; -+ if (tree_child < 0) -+ return tree_child; -+ -+ ret = overlay_update_local_node_references(fdto, -+ tree_child, -+ fixup_child, -+ delta); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * overlay_update_local_references - Adjust the overlay references -+ * @fdto: Device tree overlay blob -+ * @delta: Offset to shift the phandles of -+ * -+ * overlay_update_local_references() update all the phandles pointing -+ * to a node within the device tree overlay by adding a constant -+ * delta to not conflict with the base overlay. -+ * -+ * This is mainly used as part of a device tree application process, -+ * where you want the device tree overlays phandles to not conflict -+ * with the ones from the base device tree before merging them. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_update_local_references(void *fdto, uint32_t delta) -+{ -+ int fixups; -+ -+ fixups = fdt_path_offset(fdto, "/__local_fixups__"); -+ if (fixups < 0) { -+ /* There's no local phandles to adjust, bail out */ -+ if (fixups == -FDT_ERR_NOTFOUND) -+ return 0; -+ -+ return fixups; -+ } -+ -+ /* -+ * Update our local references from the root of the tree -+ */ -+ return overlay_update_local_node_references(fdto, 0, fixups, -+ delta); -+} -+ -+/** -+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one -+ * @fdt: Base Device Tree blob -+ * @fdto: Device tree overlay blob -+ * @symbols_off: Node offset of the symbols node in the base device tree -+ * @path: Path to a node holding a phandle in the overlay -+ * @path_len: number of path characters to consider -+ * @name: Name of the property holding the phandle reference in the overlay -+ * @name_len: number of name characters to consider -+ * @poffset: Offset within the overlay property where the phandle is stored -+ * @label: Label of the node referenced by the phandle -+ * -+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to -+ * a node in the base device tree. -+ * -+ * This is part of the device tree overlay application process, when -+ * you want all the phandles in the overlay to point to the actual -+ * base dt nodes. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_fixup_one_phandle(void *fdt, void *fdto, -+ int symbols_off, -+ const char *path, uint32_t path_len, -+ const char *name, uint32_t name_len, -+ int poffset, const char *label) -+{ -+ const char *symbol_path; -+ uint32_t phandle; -+ fdt32_t phandle_prop; -+ int symbol_off, fixup_off; -+ int prop_len; -+ -+ if (symbols_off < 0) -+ return symbols_off; -+ -+ symbol_path = fdt_getprop(fdt, symbols_off, label, -+ &prop_len); -+ if (!symbol_path) -+ return prop_len; -+ -+ symbol_off = fdt_path_offset(fdt, symbol_path); -+ if (symbol_off < 0) -+ return symbol_off; -+ -+ phandle = fdt_get_phandle(fdt, symbol_off); -+ if (!phandle) -+ return -FDT_ERR_NOTFOUND; -+ -+ fixup_off = fdt_path_offset_namelen(fdto, path, path_len); -+ if (fixup_off == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_BADOVERLAY; -+ if (fixup_off < 0) -+ return fixup_off; -+ -+ phandle_prop = cpu_to_fdt32(phandle); -+ return fdt_setprop_inplace_namelen_partial(fdto, fixup_off, -+ name, name_len, poffset, -+ &phandle_prop, -+ sizeof(phandle_prop)); -+}; -+ -+/** -+ * overlay_fixup_phandle - Set an overlay phandle to the base one -+ * @fdt: Base Device Tree blob -+ * @fdto: Device tree overlay blob -+ * @symbols_off: Node offset of the symbols node in the base device tree -+ * @property: Property offset in the overlay holding the list of fixups -+ * -+ * overlay_fixup_phandle() resolves all the overlay phandles pointed -+ * to in a __fixups__ property, and updates them to match the phandles -+ * in use in the base device tree. -+ * -+ * This is part of the device tree overlay application process, when -+ * you want all the phandles in the overlay to point to the actual -+ * base dt nodes. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, -+ int property) -+{ -+ const char *value; -+ const char *label; -+ int len; -+ -+ value = fdt_getprop_by_offset(fdto, property, -+ &label, &len); -+ if (!value) { -+ if (len == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_INTERNAL; -+ -+ return len; -+ } -+ -+ do { -+ const char *path, *name, *fixup_end; -+ const char *fixup_str = value; -+ uint32_t path_len, name_len; -+ uint32_t fixup_len; -+ char *sep, *endptr; -+ int poffset, ret; -+ -+ fixup_end = memchr(value, '\0', len); -+ if (!fixup_end) -+ return -FDT_ERR_BADOVERLAY; -+ fixup_len = fixup_end - fixup_str; -+ -+ len -= fixup_len + 1; -+ value += fixup_len + 1; -+ -+ path = fixup_str; -+ sep = memchr(fixup_str, ':', fixup_len); -+ if (!sep || *sep != ':') -+ return -FDT_ERR_BADOVERLAY; -+ -+ path_len = sep - path; -+ if (path_len == (fixup_len - 1)) -+ return -FDT_ERR_BADOVERLAY; -+ -+ fixup_len -= path_len + 1; -+ name = sep + 1; -+ sep = memchr(name, ':', fixup_len); -+ if (!sep || *sep != ':') -+ return -FDT_ERR_BADOVERLAY; -+ -+ name_len = sep - name; -+ if (!name_len) -+ return -FDT_ERR_BADOVERLAY; -+ -+ poffset = strtoul(sep + 1, &endptr, 10); -+ if ((*endptr != '\0') || (endptr <= (sep + 1))) -+ return -FDT_ERR_BADOVERLAY; -+ -+ ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, -+ path, path_len, name, name_len, -+ poffset, label); -+ if (ret) -+ return ret; -+ } while (len > 0); -+ -+ return 0; -+} -+ -+/** -+ * overlay_fixup_phandles - Resolve the overlay phandles to the base -+ * device tree -+ * @fdt: Base Device Tree blob -+ * @fdto: Device tree overlay blob -+ * -+ * overlay_fixup_phandles() resolves all the overlay phandles pointing -+ * to nodes in the base device tree. -+ * -+ * This is one of the steps of the device tree overlay application -+ * process, when you want all the phandles in the overlay to point to -+ * the actual base dt nodes. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_fixup_phandles(void *fdt, void *fdto) -+{ -+ int fixups_off, symbols_off; -+ int property; -+ -+ /* We can have overlays without any fixups */ -+ fixups_off = fdt_path_offset(fdto, "/__fixups__"); -+ if (fixups_off == -FDT_ERR_NOTFOUND) -+ return 0; /* nothing to do */ -+ if (fixups_off < 0) -+ return fixups_off; -+ -+ /* And base DTs without symbols */ -+ symbols_off = fdt_path_offset(fdt, "/__symbols__"); -+ if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))) -+ return symbols_off; -+ -+ fdt_for_each_property_offset(property, fdto, fixups_off) { -+ int ret; -+ -+ ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * overlay_apply_node - Merges a node into the base device tree -+ * @fdt: Base Device Tree blob -+ * @target: Node offset in the base device tree to apply the fragment to -+ * @fdto: Device tree overlay blob -+ * @node: Node offset in the overlay holding the changes to merge -+ * -+ * overlay_apply_node() merges a node into a target base device tree -+ * node pointed. -+ * -+ * This is part of the final step in the device tree overlay -+ * application process, when all the phandles have been adjusted and -+ * resolved and you just have to merge overlay into the base device -+ * tree. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_apply_node(void *fdt, int target, -+ void *fdto, int node) -+{ -+ int property; -+ int subnode; -+ -+ fdt_for_each_property_offset(property, fdto, node) { -+ const char *name; -+ const void *prop; -+ int prop_len; -+ int ret; -+ -+ prop = fdt_getprop_by_offset(fdto, property, &name, -+ &prop_len); -+ if (prop_len == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_INTERNAL; -+ if (prop_len < 0) -+ return prop_len; -+ -+ ret = fdt_setprop(fdt, target, name, prop, prop_len); -+ if (ret) -+ return ret; -+ } -+ -+ fdt_for_each_subnode(subnode, fdto, node) { -+ const char *name = fdt_get_name(fdto, subnode, NULL); -+ int nnode; -+ int ret; -+ -+ nnode = fdt_add_subnode(fdt, target, name); -+ if (nnode == -FDT_ERR_EXISTS) { -+ nnode = fdt_subnode_offset(fdt, target, name); -+ if (nnode == -FDT_ERR_NOTFOUND) -+ return -FDT_ERR_INTERNAL; -+ } -+ -+ if (nnode < 0) -+ return nnode; -+ -+ ret = overlay_apply_node(fdt, nnode, fdto, subnode); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * overlay_merge - Merge an overlay into its base device tree -+ * @fdt: Base Device Tree blob -+ * @fdto: Device tree overlay blob -+ * -+ * overlay_merge() merges an overlay into its base device tree. -+ * -+ * This is the next to last step in the device tree overlay application -+ * process, when all the phandles have been adjusted and resolved and -+ * you just have to merge overlay into the base device tree. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_merge(void *fdt, void *fdto) -+{ -+ int fragment; -+ -+ fdt_for_each_subnode(fragment, fdto, 0) { -+ int overlay; -+ int target; -+ int ret; -+ -+ /* -+ * Each fragments will have an __overlay__ node. If -+ * they don't, it's not supposed to be merged -+ */ -+ overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); -+ if (overlay == -FDT_ERR_NOTFOUND) -+ continue; -+ -+ if (overlay < 0) -+ return overlay; -+ -+ target = overlay_get_target(fdt, fdto, fragment, NULL); -+ if (target < 0) -+ return target; -+ -+ ret = overlay_apply_node(fdt, target, fdto, overlay); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int get_path_len(const void *fdt, int nodeoffset) -+{ -+ int len = 0, namelen; -+ const char *name; -+ -+ FDT_CHECK_HEADER(fdt); -+ -+ for (;;) { -+ name = fdt_get_name(fdt, nodeoffset, &namelen); -+ if (!name) -+ return namelen; -+ -+ /* root? we're done */ -+ if (namelen == 0) -+ break; -+ -+ nodeoffset = fdt_parent_offset(fdt, nodeoffset); -+ if (nodeoffset < 0) -+ return nodeoffset; -+ len += namelen + 1; -+ } -+ -+ /* in case of root pretend it's "/" */ -+ if (len == 0) -+ len++; -+ return len; -+} -+ -+/** -+ * overlay_symbol_update - Update the symbols of base tree after a merge -+ * @fdt: Base Device Tree blob -+ * @fdto: Device tree overlay blob -+ * -+ * overlay_symbol_update() updates the symbols of the base tree with the -+ * symbols of the applied overlay -+ * -+ * This is the last step in the device tree overlay application -+ * process, allowing the reference of overlay symbols by subsequent -+ * overlay operations. -+ * -+ * returns: -+ * 0 on success -+ * Negative error code on failure -+ */ -+static int overlay_symbol_update(void *fdt, void *fdto) -+{ -+ int root_sym, ov_sym, prop, path_len, fragment, target; -+ int len, frag_name_len, ret, rel_path_len; -+ const char *s, *e; -+ const char *path; -+ const char *name; -+ const char *frag_name; -+ const char *rel_path; -+ const char *target_path; -+ char *buf; -+ void *p; -+ -+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__"); -+ -+ /* if no overlay symbols exist no problem */ -+ if (ov_sym < 0) -+ return 0; -+ -+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__"); -+ -+ /* it no root symbols exist we should create them */ -+ if (root_sym == -FDT_ERR_NOTFOUND) -+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__"); -+ -+ /* any error is fatal now */ -+ if (root_sym < 0) -+ return root_sym; -+ -+ /* iterate over each overlay symbol */ -+ fdt_for_each_property_offset(prop, fdto, ov_sym) { -+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len); -+ if (!path) -+ return path_len; -+ -+ /* verify it's a string property (terminated by a single \0) */ -+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1]) -+ return -FDT_ERR_BADVALUE; -+ -+ /* keep end marker to avoid strlen() */ -+ e = path + path_len; -+ -+ /* format: //__overlay__/ */ -+ -+ if (*path != '/') -+ return -FDT_ERR_BADVALUE; -+ -+ /* get fragment name first */ -+ s = strchr(path + 1, '/'); -+ if (!s) -+ return -FDT_ERR_BADOVERLAY; -+ -+ frag_name = path + 1; -+ frag_name_len = s - path - 1; -+ -+ /* verify format; safe since "s" lies in \0 terminated prop */ -+ len = sizeof("/__overlay__/") - 1; -+ if ((e - s) < len || memcmp(s, "/__overlay__/", len)) -+ return -FDT_ERR_BADOVERLAY; -+ -+ rel_path = s + len; -+ rel_path_len = e - rel_path; -+ -+ /* find the fragment index in which the symbol lies */ -+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, -+ frag_name_len); -+ /* not found? */ -+ if (ret < 0) -+ return -FDT_ERR_BADOVERLAY; -+ fragment = ret; -+ -+ /* an __overlay__ subnode must exist */ -+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__"); -+ if (ret < 0) -+ return -FDT_ERR_BADOVERLAY; -+ -+ /* get the target of the fragment */ -+ ret = overlay_get_target(fdt, fdto, fragment, &target_path); -+ if (ret < 0) -+ return ret; -+ target = ret; -+ -+ /* if we have a target path use */ -+ if (!target_path) { -+ ret = get_path_len(fdt, target); -+ if (ret < 0) -+ return ret; -+ len = ret; -+ } else { -+ len = strlen(target_path); -+ } -+ -+ ret = fdt_setprop_placeholder(fdt, root_sym, name, -+ len + (len > 1) + rel_path_len + 1, &p); -+ if (ret < 0) -+ return ret; -+ -+ if (!target_path) { -+ /* again in case setprop_placeholder changed it */ -+ ret = overlay_get_target(fdt, fdto, fragment, &target_path); -+ if (ret < 0) -+ return ret; -+ target = ret; -+ } -+ -+ buf = p; -+ if (len > 1) { /* target is not root */ -+ if (!target_path) { -+ ret = fdt_get_path(fdt, target, buf, len + 1); -+ if (ret < 0) -+ return ret; -+ } else -+ memcpy(buf, target_path, len + 1); -+ -+ } else -+ len--; -+ -+ buf[len] = '/'; -+ memcpy(buf + len + 1, rel_path, rel_path_len); -+ buf[len + 1 + rel_path_len] = '\0'; -+ } -+ -+ return 0; -+} -+ -+int fdt_overlay_apply(void *fdt, void *fdto) -+{ -+ uint32_t delta = fdt_get_max_phandle(fdt); -+ int ret; -+ -+ FDT_CHECK_HEADER(fdt); -+ FDT_CHECK_HEADER(fdto); -+ -+ ret = overlay_adjust_local_phandles(fdto, delta); -+ if (ret) -+ goto err; -+ -+ ret = overlay_update_local_references(fdto, delta); -+ if (ret) -+ goto err; -+ -+ ret = overlay_fixup_phandles(fdt, fdto); -+ if (ret) -+ goto err; -+ -+ ret = overlay_merge(fdt, fdto); -+ if (ret) -+ goto err; -+ -+ ret = overlay_symbol_update(fdt, fdto); -+ if (ret) -+ goto err; -+ -+ /* -+ * The overlay has been damaged, erase its magic. -+ */ -+ fdt_set_magic(fdto, ~0); -+ -+ return 0; -+ -+err: -+ /* -+ * The overlay might have been damaged, erase its magic. -+ */ -+ fdt_set_magic(fdto, ~0); -+ -+ /* -+ * The base device tree might have been damaged, erase its -+ * magic. -+ */ -+ fdt_set_magic(fdt, ~0); -+ -+ return ret; -+} -diff --git a/scripts/dtc/fdt_ro.c b/scripts/dtc/fdt_ro.c -index 50007f61c..dfb3236da 100644 ---- a/scripts/dtc/fdt_ro.c -+++ b/scripts/dtc/fdt_ro.c -@@ -55,12 +55,13 @@ - - #include "libfdt_internal.h" - --static int _fdt_nodename_eq(const void *fdt, int offset, -+static int fdt_nodename_eq_(const void *fdt, int offset, - const char *s, int len) - { -- const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); -+ int olen; -+ const char *p = fdt_get_name(fdt, offset, &olen); - -- if (! p) -+ if (!p || olen < len) - /* short match */ - return 0; - -@@ -80,7 +81,7 @@ const char *fdt_string(const void *fdt, int stroffset) - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; - } - --static int _fdt_string_eq(const void *fdt, int stroffset, -+static int fdt_string_eq_(const void *fdt, int stroffset, - const char *s, int len) - { - const char *p = fdt_string(fdt, stroffset); -@@ -88,11 +89,37 @@ static int _fdt_string_eq(const void *fdt, int stroffset, - return (strlen(p) == len) && (memcmp(p, s, len) == 0); - } - -+uint32_t fdt_get_max_phandle(const void *fdt) -+{ -+ uint32_t max_phandle = 0; -+ int offset; -+ -+ for (offset = fdt_next_node(fdt, -1, NULL);; -+ offset = fdt_next_node(fdt, offset, NULL)) { -+ uint32_t phandle; -+ -+ if (offset == -FDT_ERR_NOTFOUND) -+ return max_phandle; -+ -+ if (offset < 0) -+ return (uint32_t)-1; -+ -+ phandle = fdt_get_phandle(fdt, offset); -+ if (phandle == (uint32_t)-1) -+ continue; -+ -+ if (phandle > max_phandle) -+ max_phandle = phandle; -+ } -+ -+ return 0; -+} -+ - int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) - { - FDT_CHECK_HEADER(fdt); -- *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); -- *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); -+ *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); -+ *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); - return 0; - } - -@@ -100,12 +127,12 @@ int fdt_num_mem_rsv(const void *fdt) - { - int i = 0; - -- while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) -+ while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) - i++; - return i; - } - --static int _nextprop(const void *fdt, int offset) -+static int nextprop_(const void *fdt, int offset) - { - uint32_t tag; - int nextoffset; -@@ -140,7 +167,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, - (offset >= 0) && (depth >= 0); - offset = fdt_next_node(fdt, offset, &depth)) - if ((depth == 1) -- && _fdt_nodename_eq(fdt, offset, name, namelen)) -+ && fdt_nodename_eq_(fdt, offset, name, namelen)) - return offset; - - if (depth < 0) -@@ -154,9 +181,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, - return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); - } - --int fdt_path_offset(const void *fdt, const char *path) -+int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) - { -- const char *end = path + strlen(path); -+ const char *end = path + namelen; - const char *p = path; - int offset = 0; - -@@ -164,7 +191,7 @@ int fdt_path_offset(const void *fdt, const char *path) - - /* see if we have an alias */ - if (*path != '/') { -- const char *q = strchr(path, '/'); -+ const char *q = memchr(path, '/', end - p); - - if (!q) - q = end; -@@ -177,14 +204,15 @@ int fdt_path_offset(const void *fdt, const char *path) - p = q; - } - -- while (*p) { -+ while (p < end) { - const char *q; - -- while (*p == '/') -+ while (*p == '/') { - p++; -- if (! *p) -- return offset; -- q = strchr(p, '/'); -+ if (p == end) -+ return offset; -+ } -+ q = memchr(p, '/', end - p); - if (! q) - q = end; - -@@ -198,19 +226,42 @@ int fdt_path_offset(const void *fdt, const char *path) - return offset; - } - -+int fdt_path_offset(const void *fdt, const char *path) -+{ -+ return fdt_path_offset_namelen(fdt, path, strlen(path)); -+} -+ - const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) - { -- const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); -+ const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); -+ const char *nameptr; - int err; - - if (((err = fdt_check_header(fdt)) != 0) -- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) -+ || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) - goto fail; - -+ nameptr = nh->name; -+ -+ if (fdt_version(fdt) < 0x10) { -+ /* -+ * For old FDT versions, match the naming conventions of V16: -+ * give only the leaf name (after all /). The actual tree -+ * contents are loosely checked. -+ */ -+ const char *leaf; -+ leaf = strrchr(nameptr, '/'); -+ if (leaf == NULL) { -+ err = -FDT_ERR_BADSTRUCTURE; -+ goto fail; -+ } -+ nameptr = leaf+1; -+ } -+ - if (len) -- *len = strlen(nh->name); -+ *len = strlen(nameptr); - -- return nh->name; -+ return nameptr; - - fail: - if (len) -@@ -222,34 +273,34 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset) - { - int offset; - -- if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) -+ if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) - return offset; - -- return _nextprop(fdt, offset); -+ return nextprop_(fdt, offset); - } - - int fdt_next_property_offset(const void *fdt, int offset) - { -- if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) -+ if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) - return offset; - -- return _nextprop(fdt, offset); -+ return nextprop_(fdt, offset); - } - --const struct fdt_property *fdt_get_property_by_offset(const void *fdt, -- int offset, -- int *lenp) -+static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, -+ int offset, -+ int *lenp) - { - int err; - const struct fdt_property *prop; - -- if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { -+ if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { - if (lenp) - *lenp = err; - return NULL; - } - -- prop = _fdt_offset_ptr(fdt, offset); -+ prop = fdt_offset_ptr_(fdt, offset); - - if (lenp) - *lenp = fdt32_to_cpu(prop->len); -@@ -257,23 +308,44 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - return prop; - } - --const struct fdt_property *fdt_get_property_namelen(const void *fdt, -- int offset, -- const char *name, -- int namelen, int *lenp) -+const struct fdt_property *fdt_get_property_by_offset(const void *fdt, -+ int offset, -+ int *lenp) -+{ -+ /* Prior to version 16, properties may need realignment -+ * and this API does not work. fdt_getprop_*() will, however. */ -+ -+ if (fdt_version(fdt) < 0x10) { -+ if (lenp) -+ *lenp = -FDT_ERR_BADVERSION; -+ return NULL; -+ } -+ -+ return fdt_get_property_by_offset_(fdt, offset, lenp); -+} -+ -+static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, -+ int offset, -+ const char *name, -+ int namelen, -+ int *lenp, -+ int *poffset) - { - for (offset = fdt_first_property_offset(fdt, offset); - (offset >= 0); - (offset = fdt_next_property_offset(fdt, offset))) { - const struct fdt_property *prop; - -- if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { -+ if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) { - offset = -FDT_ERR_INTERNAL; - break; - } -- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), -- name, namelen)) -+ if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), -+ name, namelen)) { -+ if (poffset) -+ *poffset = offset; - return prop; -+ } - } - - if (lenp) -@@ -281,6 +353,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, - return NULL; - } - -+ -+const struct fdt_property *fdt_get_property_namelen(const void *fdt, -+ int offset, -+ const char *name, -+ int namelen, int *lenp) -+{ -+ /* Prior to version 16, properties may need realignment -+ * and this API does not work. fdt_getprop_*() will, however. */ -+ if (fdt_version(fdt) < 0x10) { -+ if (lenp) -+ *lenp = -FDT_ERR_BADVERSION; -+ return NULL; -+ } -+ -+ return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, -+ NULL); -+} -+ -+ - const struct fdt_property *fdt_get_property(const void *fdt, - int nodeoffset, - const char *name, int *lenp) -@@ -292,12 +383,18 @@ const struct fdt_property *fdt_get_property(const void *fdt, - const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp) - { -+ int poffset; - const struct fdt_property *prop; - -- prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); -- if (! prop) -+ prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, -+ &poffset); -+ if (!prop) - return NULL; - -+ /* Handle realignment */ -+ if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && -+ fdt32_to_cpu(prop->len) >= 8) -+ return prop->data + 4; - return prop->data; - } - -@@ -306,11 +403,16 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, - { - const struct fdt_property *prop; - -- prop = fdt_get_property_by_offset(fdt, offset, lenp); -+ prop = fdt_get_property_by_offset_(fdt, offset, lenp); - if (!prop) - return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); -+ -+ /* Handle realignment */ -+ if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && -+ fdt32_to_cpu(prop->len) >= 8) -+ return prop->data + 4; - return prop->data; - } - -@@ -532,6 +634,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) - return 0; - } - -+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) -+{ -+ const char *list, *end; -+ int length, count = 0; -+ -+ list = fdt_getprop(fdt, nodeoffset, property, &length); -+ if (!list) -+ return length; -+ -+ end = list + length; -+ -+ while (list < end) { -+ length = strnlen(list, end - list) + 1; -+ -+ /* Abort if the last string isn't properly NUL-terminated. */ -+ if (list + length > end) -+ return -FDT_ERR_BADVALUE; -+ -+ list += length; -+ count++; -+ } -+ -+ return count; -+} -+ -+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, -+ const char *string) -+{ -+ int length, len, idx = 0; -+ const char *list, *end; -+ -+ list = fdt_getprop(fdt, nodeoffset, property, &length); -+ if (!list) -+ return length; -+ -+ len = strlen(string) + 1; -+ end = list + length; -+ -+ while (list < end) { -+ length = strnlen(list, end - list) + 1; -+ -+ /* Abort if the last string isn't properly NUL-terminated. */ -+ if (list + length > end) -+ return -FDT_ERR_BADVALUE; -+ -+ if (length == len && memcmp(list, string, length) == 0) -+ return idx; -+ -+ list += length; -+ idx++; -+ } -+ -+ return -FDT_ERR_NOTFOUND; -+} -+ -+const char *fdt_stringlist_get(const void *fdt, int nodeoffset, -+ const char *property, int idx, -+ int *lenp) -+{ -+ const char *list, *end; -+ int length; -+ -+ list = fdt_getprop(fdt, nodeoffset, property, &length); -+ if (!list) { -+ if (lenp) -+ *lenp = length; -+ -+ return NULL; -+ } -+ -+ end = list + length; -+ -+ while (list < end) { -+ length = strnlen(list, end - list) + 1; -+ -+ /* Abort if the last string isn't properly NUL-terminated. */ -+ if (list + length > end) { -+ if (lenp) -+ *lenp = -FDT_ERR_BADVALUE; -+ -+ return NULL; -+ } -+ -+ if (idx == 0) { -+ if (lenp) -+ *lenp = length - 1; -+ -+ return list; -+ } -+ -+ list += length; -+ idx--; -+ } -+ -+ if (lenp) -+ *lenp = -FDT_ERR_NOTFOUND; -+ -+ return NULL; -+} -+ - int fdt_node_check_compatible(const void *fdt, int nodeoffset, - const char *compatible) - { -@@ -541,10 +743,8 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, - prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); - if (!prop) - return len; -- if (fdt_stringlist_contains(prop, len, compatible)) -- return 0; -- else -- return 1; -+ -+ return !fdt_stringlist_contains(prop, len, compatible); - } - - int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -diff --git a/scripts/dtc/fdt_rw.c b/scripts/dtc/fdt_rw.c -index 70adec6c3..9b829051e 100644 ---- a/scripts/dtc/fdt_rw.c -+++ b/scripts/dtc/fdt_rw.c -@@ -55,8 +55,8 @@ - - #include "libfdt_internal.h" - --static int _fdt_blocks_misordered(const void *fdt, -- int mem_rsv_size, int struct_size) -+static int fdt_blocks_misordered_(const void *fdt, -+ int mem_rsv_size, int struct_size) - { - return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) - || (fdt_off_dt_struct(fdt) < -@@ -67,13 +67,13 @@ static int _fdt_blocks_misordered(const void *fdt, - (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); - } - --static int _fdt_rw_check_header(void *fdt) -+static int fdt_rw_check_header_(void *fdt) - { - FDT_CHECK_HEADER(fdt); - - if (fdt_version(fdt) < 17) - return -FDT_ERR_BADVERSION; -- if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), -+ if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), - fdt_size_dt_struct(fdt))) - return -FDT_ERR_BADLAYOUT; - if (fdt_version(fdt) > 17) -@@ -84,35 +84,37 @@ static int _fdt_rw_check_header(void *fdt) - - #define FDT_RW_CHECK_HEADER(fdt) \ - { \ -- int __err; \ -- if ((__err = _fdt_rw_check_header(fdt)) != 0) \ -- return __err; \ -+ int err_; \ -+ if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ -+ return err_; \ - } - --static inline int _fdt_data_size(void *fdt) -+static inline int fdt_data_size_(void *fdt) - { - return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); - } - --static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) -+static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) - { - char *p = splicepoint; -- char *end = (char *)fdt + _fdt_data_size(fdt); -+ char *end = (char *)fdt + fdt_data_size_(fdt); - - if (((p + oldlen) < p) || ((p + oldlen) > end)) - return -FDT_ERR_BADOFFSET; -+ if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) -+ return -FDT_ERR_BADOFFSET; - if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) - return -FDT_ERR_NOSPACE; - memmove(p + newlen, p + oldlen, end - p - oldlen); - return 0; - } - --static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, -+static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p, - int oldn, int newn) - { - int delta = (newn - oldn) * sizeof(*p); - int err; -- err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); -+ err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); - if (err) - return err; - fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); -@@ -120,13 +122,13 @@ static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, - return 0; - } - --static int _fdt_splice_struct(void *fdt, void *p, -+static int fdt_splice_struct_(void *fdt, void *p, - int oldlen, int newlen) - { - int delta = newlen - oldlen; - int err; - -- if ((err = _fdt_splice(fdt, p, oldlen, newlen))) -+ if ((err = fdt_splice_(fdt, p, oldlen, newlen))) - return err; - - fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); -@@ -134,20 +136,20 @@ static int _fdt_splice_struct(void *fdt, void *p, - return 0; - } - --static int _fdt_splice_string(void *fdt, int newlen) -+static int fdt_splice_string_(void *fdt, int newlen) - { - void *p = (char *)fdt - + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); - int err; - -- if ((err = _fdt_splice(fdt, p, 0, newlen))) -+ if ((err = fdt_splice_(fdt, p, 0, newlen))) - return err; - - fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); - return 0; - } - --static int _fdt_find_add_string(void *fdt, const char *s) -+static int fdt_find_add_string_(void *fdt, const char *s) - { - char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); - const char *p; -@@ -155,13 +157,13 @@ static int _fdt_find_add_string(void *fdt, const char *s) - int len = strlen(s) + 1; - int err; - -- p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); -+ p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); - if (p) - /* found it */ - return (p - strtab); - - new = strtab + fdt_size_dt_strings(fdt); -- err = _fdt_splice_string(fdt, len); -+ err = fdt_splice_string_(fdt, len); - if (err) - return err; - -@@ -176,8 +178,8 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) - - FDT_RW_CHECK_HEADER(fdt); - -- re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); -- err = _fdt_splice_mem_rsv(fdt, re, 0, 1); -+ re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); -+ err = fdt_splice_mem_rsv_(fdt, re, 0, 1); - if (err) - return err; - -@@ -188,31 +190,27 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) - - int fdt_del_mem_rsv(void *fdt, int n) - { -- struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); -- int err; -+ struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); - - FDT_RW_CHECK_HEADER(fdt); - - if (n >= fdt_num_mem_rsv(fdt)) - return -FDT_ERR_NOTFOUND; - -- err = _fdt_splice_mem_rsv(fdt, re, 1, 0); -- if (err) -- return err; -- return 0; -+ return fdt_splice_mem_rsv_(fdt, re, 1, 0); - } - --static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, -+static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) - { - int oldlen; - int err; - - *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); -- if (! (*prop)) -+ if (!*prop) - return oldlen; - -- if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), -+ if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), - FDT_TAGALIGN(len)))) - return err; - -@@ -220,7 +218,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, - return 0; - } - --static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, -+static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) - { - int proplen; -@@ -228,17 +226,17 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, - int namestroff; - int err; - -- if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) -+ if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) - return nextoffset; - -- namestroff = _fdt_find_add_string(fdt, name); -+ namestroff = fdt_find_add_string_(fdt, name); - if (namestroff < 0) - return namestroff; - -- *prop = _fdt_offset_ptr_w(fdt, nextoffset); -+ *prop = fdt_offset_ptr_w_(fdt, nextoffset); - proplen = sizeof(**prop) + FDT_TAGALIGN(len); - -- err = _fdt_splice_struct(fdt, *prop, 0, proplen); -+ err = fdt_splice_struct_(fdt, *prop, 0, proplen); - if (err) - return err; - -@@ -262,7 +260,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) - - newlen = strlen(name); - -- err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), -+ err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), - FDT_TAGALIGN(newlen+1)); - if (err) - return err; -@@ -271,21 +269,36 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) - return 0; - } - --int fdt_setprop(void *fdt, int nodeoffset, const char *name, -- const void *val, int len) -+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, -+ int len, void **prop_data) - { - struct fdt_property *prop; - int err; - - FDT_RW_CHECK_HEADER(fdt); - -- err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); -+ err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); - if (err == -FDT_ERR_NOTFOUND) -- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); -+ err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); -+ if (err) -+ return err; -+ -+ *prop_data = prop->data; -+ return 0; -+} -+ -+int fdt_setprop(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len) -+{ -+ void *prop_data; -+ int err; -+ -+ err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data); - if (err) - return err; - -- memcpy(prop->data, val, len); -+ if (len) -+ memcpy(prop_data, val, len); - return 0; - } - -@@ -300,7 +313,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, - prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); - if (prop) { - newlen = len + oldlen; -- err = _fdt_splice_struct(fdt, prop->data, -+ err = fdt_splice_struct_(fdt, prop->data, - FDT_TAGALIGN(oldlen), - FDT_TAGALIGN(newlen)); - if (err) -@@ -308,7 +321,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, - prop->len = cpu_to_fdt32(newlen); - memcpy(prop->data + oldlen, val, len); - } else { -- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); -+ err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); - if (err) - return err; - memcpy(prop->data, val, len); -@@ -324,11 +337,11 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) - FDT_RW_CHECK_HEADER(fdt); - - prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -- if (! prop) -+ if (!prop) - return len; - - proplen = sizeof(*prop) + FDT_TAGALIGN(len); -- return _fdt_splice_struct(fdt, prop, proplen, 0); -+ return fdt_splice_struct_(fdt, prop, proplen, 0); - } - - int fdt_add_subnode_namelen(void *fdt, int parentoffset, -@@ -356,10 +369,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, - tag = fdt_next_tag(fdt, offset, &nextoffset); - } while ((tag == FDT_PROP) || (tag == FDT_NOP)); - -- nh = _fdt_offset_ptr_w(fdt, offset); -+ nh = fdt_offset_ptr_w_(fdt, offset); - nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; - -- err = _fdt_splice_struct(fdt, nh, 0, nodelen); -+ err = fdt_splice_struct_(fdt, nh, 0, nodelen); - if (err) - return err; - -@@ -383,15 +396,15 @@ int fdt_del_node(void *fdt, int nodeoffset) - - FDT_RW_CHECK_HEADER(fdt); - -- endoffset = _fdt_node_end_offset(fdt, nodeoffset); -+ endoffset = fdt_node_end_offset_(fdt, nodeoffset); - if (endoffset < 0) - return endoffset; - -- return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), -+ return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), - endoffset - nodeoffset, 0); - } - --static void _fdt_packblocks(const char *old, char *new, -+static void fdt_packblocks_(const char *old, char *new, - int mem_rsv_size, int struct_size) - { - int mem_rsv_off, struct_off, strings_off; -@@ -437,7 +450,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) - return struct_size; - } - -- if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { -+ if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { - /* no further work necessary */ - err = fdt_move(fdt, buf, bufsize); - if (err) -@@ -465,7 +478,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) - return -FDT_ERR_NOSPACE; - } - -- _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); -+ fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); - memmove(buf, tmp, newsize); - - fdt_set_magic(buf, FDT_MAGIC); -@@ -485,8 +498,8 @@ int fdt_pack(void *fdt) - - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) - * sizeof(struct fdt_reserve_entry); -- _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); -- fdt_set_totalsize(fdt, _fdt_data_size(fdt)); -+ fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); -+ fdt_set_totalsize(fdt, fdt_data_size_(fdt)); - - return 0; - } -diff --git a/scripts/dtc/fdt_strerror.c b/scripts/dtc/fdt_strerror.c -index e6c3ceee8..9677a1887 100644 ---- a/scripts/dtc/fdt_strerror.c -+++ b/scripts/dtc/fdt_strerror.c -@@ -69,6 +69,7 @@ static struct fdt_errtabent fdt_errtable[] = { - - FDT_ERRTABENT(FDT_ERR_BADOFFSET), - FDT_ERRTABENT(FDT_ERR_BADPATH), -+ FDT_ERRTABENT(FDT_ERR_BADPHANDLE), - FDT_ERRTABENT(FDT_ERR_BADSTATE), - - FDT_ERRTABENT(FDT_ERR_TRUNCATED), -@@ -76,6 +77,11 @@ static struct fdt_errtabent fdt_errtable[] = { - FDT_ERRTABENT(FDT_ERR_BADVERSION), - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), - FDT_ERRTABENT(FDT_ERR_BADLAYOUT), -+ FDT_ERRTABENT(FDT_ERR_INTERNAL), -+ FDT_ERRTABENT(FDT_ERR_BADNCELLS), -+ FDT_ERRTABENT(FDT_ERR_BADVALUE), -+ FDT_ERRTABENT(FDT_ERR_BADOVERLAY), -+ FDT_ERRTABENT(FDT_ERR_NOPHANDLES), - }; - #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) - -diff --git a/scripts/dtc/fdt_sw.c b/scripts/dtc/fdt_sw.c -index 6a804859f..6d33cc29d 100644 ---- a/scripts/dtc/fdt_sw.c -+++ b/scripts/dtc/fdt_sw.c -@@ -55,7 +55,7 @@ - - #include "libfdt_internal.h" - --static int _fdt_sw_check_header(void *fdt) -+static int fdt_sw_check_header_(void *fdt) - { - if (fdt_magic(fdt) != FDT_SW_MAGIC) - return -FDT_ERR_BADMAGIC; -@@ -66,11 +66,11 @@ static int _fdt_sw_check_header(void *fdt) - #define FDT_SW_CHECK_HEADER(fdt) \ - { \ - int err; \ -- if ((err = _fdt_sw_check_header(fdt)) != 0) \ -+ if ((err = fdt_sw_check_header_(fdt)) != 0) \ - return err; \ - } - --static void *_fdt_grab_space(void *fdt, size_t len) -+static void *fdt_grab_space_(void *fdt, size_t len) - { - int offset = fdt_size_dt_struct(fdt); - int spaceleft; -@@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, size_t len) - return NULL; - - fdt_set_size_dt_struct(fdt, offset + len); -- return _fdt_offset_ptr_w(fdt, offset); -+ return fdt_offset_ptr_w_(fdt, offset); - } - - int fdt_create(void *buf, int bufsize) -@@ -174,7 +174,7 @@ int fdt_begin_node(void *fdt, const char *name) - - FDT_SW_CHECK_HEADER(fdt); - -- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); -+ nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); - if (! nh) - return -FDT_ERR_NOSPACE; - -@@ -189,7 +189,7 @@ int fdt_end_node(void *fdt) - - FDT_SW_CHECK_HEADER(fdt); - -- en = _fdt_grab_space(fdt, FDT_TAGSIZE); -+ en = fdt_grab_space_(fdt, FDT_TAGSIZE); - if (! en) - return -FDT_ERR_NOSPACE; - -@@ -197,7 +197,7 @@ int fdt_end_node(void *fdt) - return 0; - } - --static int _fdt_find_add_string(void *fdt, const char *s) -+static int fdt_find_add_string_(void *fdt, const char *s) - { - char *strtab = (char *)fdt + fdt_totalsize(fdt); - const char *p; -@@ -205,7 +205,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) - int len = strlen(s) + 1; - int struct_top, offset; - -- p = _fdt_find_string(strtab - strtabsize, strtabsize, s); -+ p = fdt_find_string_(strtab - strtabsize, strtabsize, s); - if (p) - return p - strtab; - -@@ -220,25 +220,37 @@ static int _fdt_find_add_string(void *fdt, const char *s) - return offset; - } - --int fdt_property(void *fdt, const char *name, const void *val, int len) -+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) - { - struct fdt_property *prop; - int nameoff; - - FDT_SW_CHECK_HEADER(fdt); - -- nameoff = _fdt_find_add_string(fdt, name); -+ nameoff = fdt_find_add_string_(fdt, name); - if (nameoff == 0) - return -FDT_ERR_NOSPACE; - -- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); -+ prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); - if (! prop) - return -FDT_ERR_NOSPACE; - - prop->tag = cpu_to_fdt32(FDT_PROP); - prop->nameoff = cpu_to_fdt32(nameoff); - prop->len = cpu_to_fdt32(len); -- memcpy(prop->data, val, len); -+ *valp = prop->data; -+ return 0; -+} -+ -+int fdt_property(void *fdt, const char *name, const void *val, int len) -+{ -+ void *ptr; -+ int ret; -+ -+ ret = fdt_property_placeholder(fdt, name, len, &ptr); -+ if (ret) -+ return ret; -+ memcpy(ptr, val, len); - return 0; - } - -@@ -253,7 +265,7 @@ int fdt_finish(void *fdt) - FDT_SW_CHECK_HEADER(fdt); - - /* Add terminator */ -- end = _fdt_grab_space(fdt, sizeof(*end)); -+ end = fdt_grab_space_(fdt, sizeof(*end)); - if (! end) - return -FDT_ERR_NOSPACE; - *end = cpu_to_fdt32(FDT_END); -@@ -269,7 +281,7 @@ int fdt_finish(void *fdt) - while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { - if (tag == FDT_PROP) { - struct fdt_property *prop = -- _fdt_offset_ptr_w(fdt, offset); -+ fdt_offset_ptr_w_(fdt, offset); - int nameoff; - - nameoff = fdt32_to_cpu(prop->nameoff); -diff --git a/scripts/dtc/fdt_wip.c b/scripts/dtc/fdt_wip.c -index c5bbb68d3..534c1cbbb 100644 ---- a/scripts/dtc/fdt_wip.c -+++ b/scripts/dtc/fdt_wip.c -@@ -55,24 +55,45 @@ - - #include "libfdt_internal.h" - -+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ uint32_t idx, const void *val, -+ int len) -+{ -+ void *propval; -+ int proplen; -+ -+ propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen, -+ &proplen); -+ if (!propval) -+ return proplen; -+ -+ if (proplen < (len + idx)) -+ return -FDT_ERR_NOSPACE; -+ -+ memcpy((char *)propval + idx, val, len); -+ return 0; -+} -+ - int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, - const void *val, int len) - { -- void *propval; -+ const void *propval; - int proplen; - -- propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); -- if (! propval) -+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen); -+ if (!propval) - return proplen; - - if (proplen != len) - return -FDT_ERR_NOSPACE; - -- memcpy(propval, val, len); -- return 0; -+ return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, -+ strlen(name), 0, -+ val, len); - } - --static void _fdt_nop_region(void *start, int len) -+static void fdt_nop_region_(void *start, int len) - { - fdt32_t *p; - -@@ -86,15 +107,15 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) - int len; - - prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -- if (! prop) -+ if (!prop) - return len; - -- _fdt_nop_region(prop, len + sizeof(*prop)); -+ fdt_nop_region_(prop, len + sizeof(*prop)); - - return 0; - } - --int _fdt_node_end_offset(void *fdt, int offset) -+int fdt_node_end_offset_(void *fdt, int offset) - { - int depth = 0; - -@@ -108,11 +129,11 @@ int fdt_nop_node(void *fdt, int nodeoffset) - { - int endoffset; - -- endoffset = _fdt_node_end_offset(fdt, nodeoffset); -+ endoffset = fdt_node_end_offset_(fdt, nodeoffset); - if (endoffset < 0) - return endoffset; - -- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), -+ fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0), - endoffset - nodeoffset); - return 0; - } -diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c -index 95a6a2016..7d460a50b 100644 ---- a/scripts/dtc/fdtdump.c -+++ b/scripts/dtc/fdtdump.c -@@ -1,17 +1,16 @@ -+// SPDX-License-Identifier: GPL-2.0 - /* - * fdtdump.c - Contributed by Pantelis Antoniou - */ - --#include - #include - #include - #include - #include - #include - --#include --#include - #include -+#include - - #include "util.h" - -@@ -19,29 +18,33 @@ - #define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) - #define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) - --static const char *tagname(uint32_t tag) -+static void print_data(const char *data, int len) - { -- static const char * const names[] = { --#define TN(t) [t] = #t -- TN(FDT_BEGIN_NODE), -- TN(FDT_END_NODE), -- TN(FDT_PROP), -- TN(FDT_NOP), -- TN(FDT_END), --#undef TN -- }; -- if (tag < ARRAY_SIZE(names)) -- if (names[tag]) -- return names[tag]; -- return "FDT_???"; -+ int i; -+ const char *p = data; -+ -+ /* no data, don't print */ -+ if (len == 0) -+ return; -+ -+ if (util_is_printable_string(data, len)) { -+ printf(" = \"%s\"", (const char *)data); -+ } else if ((len % 4) == 0) { -+ printf(" = <"); -+ for (i = 0; i < len; i += 4) -+ printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)), -+ i < (len - 4) ? " " : ""); -+ printf(">"); -+ } else { -+ printf(" = ["); -+ for (i = 0; i < len; i++) -+ printf("%02x%s", *p++, i < len - 1 ? " " : ""); -+ printf("]"); -+ } - } - --#define dumpf(fmt, args...) \ -- do { if (debug) printf("// " fmt, ## args); } while (0) -- --static void dump_blob(void *blob, bool debug) -+static void dump_blob(void *blob) - { -- uintptr_t blob_off = (uintptr_t)blob; - struct fdt_header *bph = blob; - uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap); - uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct); -@@ -88,15 +91,14 @@ static void dump_blob(void *blob, bool debug) - if (addr == 0 && size == 0) - break; - -- printf("/memreserve/ %#llx %#llx;\n", -+ printf("/memreserve/ %llx %llx;\n", - (unsigned long long)addr, (unsigned long long)size); - } - - p = p_struct; - while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { - -- dumpf("%04zx: tag: 0x%08x (%s)\n", -- (uintptr_t)p - blob_off - 4, tag, tagname(tag)); -+ /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ - - if (tag == FDT_BEGIN_NODE) { - s = p; -@@ -135,93 +137,27 @@ static void dump_blob(void *blob, bool debug) - - p = PALIGN(p + sz, 4); - -- dumpf("%04zx: string: %s\n", (uintptr_t)s - blob_off, s); -- dumpf("%04zx: value\n", (uintptr_t)t - blob_off); - printf("%*s%s", depth * shift, "", s); -- utilfdt_print_data(t, sz); -+ print_data(t, sz); - printf(";\n"); - } - } - --/* Usage related data. */ --static const char usage_synopsis[] = "fdtdump [options] "; --static const char usage_short_opts[] = "ds" USAGE_COMMON_SHORT_OPTS; --static struct option const usage_long_opts[] = { -- {"debug", no_argument, NULL, 'd'}, -- {"scan", no_argument, NULL, 's'}, -- USAGE_COMMON_LONG_OPTS --}; --static const char * const usage_opts_help[] = { -- "Dump debug information while decoding the file", -- "Scan for an embedded fdt in file", -- USAGE_COMMON_OPTS_HELP --}; - - int main(int argc, char *argv[]) - { -- int opt; -- const char *file; - char *buf; -- bool debug = false; -- bool scan = false; -- off_t len; -- -- while ((opt = util_getopt_long()) != EOF) { -- switch (opt) { -- case_USAGE_COMMON_FLAGS - -- case 'd': -- debug = true; -- break; -- case 's': -- scan = true; -- break; -- } -- } -- if (optind != argc - 1) -- usage("missing input filename"); -- file = argv[optind]; -- -- buf = utilfdt_read_len(file, &len); -- if (!buf) -- die("could not read: %s\n", file); -- -- /* try and locate an embedded fdt in a bigger blob */ -- if (scan) { -- unsigned char smagic[4]; -- char *p = buf; -- char *endp = buf + len; -- -- fdt_set_magic(smagic, FDT_MAGIC); -- -- /* poor man's memmem */ -- while (true) { -- p = memchr(p, smagic[0], endp - p - 4); -- if (!p) -- break; -- if (fdt_magic(p) == FDT_MAGIC) { -- /* try and validate the main struct */ -- off_t this_len = endp - p; -- fdt32_t max_version = 17; -- if (fdt_version(p) <= max_version && -- fdt_last_comp_version(p) < max_version && -- fdt_totalsize(p) < this_len && -- fdt_off_dt_struct(p) < this_len && -- fdt_off_dt_strings(p) < this_len) -- break; -- if (debug) -- printf("%s: skipping fdt magic at offset %#zx\n", -- file, p - buf); -- } -- ++p; -- } -- if (!p) -- die("%s: could not locate fdt magic\n", file); -- printf("%s: found fdt at offset %#zx\n", file, p - buf); -- buf = p; -+ if (argc < 2) { -+ fprintf(stderr, "supply input filename\n"); -+ return 5; - } - -- dump_blob(buf, debug); -+ buf = utilfdt_read(argv[1]); -+ if (buf) -+ dump_blob(buf); -+ else -+ return 10; - - return 0; - } -diff --git a/scripts/dtc/fdtget.c b/scripts/dtc/fdtget.c -index 437741922..c2fbab2a5 100644 ---- a/scripts/dtc/fdtget.c -+++ b/scripts/dtc/fdtget.c -@@ -277,33 +277,33 @@ static int do_fdtget(struct display_info *disp, const char *filename, - return 0; - } - --/* Usage related data. */ --static const char usage_synopsis[] = -- "read values from device tree\n" -+static const char *usage_msg = -+ "fdtget - read values from device tree\n" -+ "\n" -+ "Each value is printed on a new line.\n\n" -+ "Usage:\n" - " fdtget
[ ]...\n" - " fdtget -p
[ ]...\n" -- "\n" -- "Each value is printed on a new line.\n" -+ "Options:\n" -+ "\t-t \tType of data\n" -+ "\t-p\t\tList properties for each node\n" -+ "\t-l\t\tList subnodes for each node\n" -+ "\t-d\t\tDefault value to display when the property is " -+ "missing\n" -+ "\t-h\t\tPrint this help\n\n" - USAGE_TYPE_MSG; --static const char usage_short_opts[] = "t:pld:" USAGE_COMMON_SHORT_OPTS; --static struct option const usage_long_opts[] = { -- {"type", a_argument, NULL, 't'}, -- {"properties", no_argument, NULL, 'p'}, -- {"list", no_argument, NULL, 'l'}, -- {"default", a_argument, NULL, 'd'}, -- USAGE_COMMON_LONG_OPTS, --}; --static const char * const usage_opts_help[] = { -- "Type of data", -- "List properties for each node", -- "List subnodes for each node", -- "Default value to display when the property is missing", -- USAGE_COMMON_OPTS_HELP --}; -+ -+static void usage(const char *msg) -+{ -+ if (msg) -+ fprintf(stderr, "Error: %s\n\n", msg); -+ -+ fprintf(stderr, "%s", usage_msg); -+ exit(2); -+} - - int main(int argc, char *argv[]) - { -- int opt; - char *filename = NULL; - struct display_info disp; - int args_per_step = 2; -@@ -312,14 +312,20 @@ int main(int argc, char *argv[]) - memset(&disp, '\0', sizeof(disp)); - disp.size = -1; - disp.mode = MODE_SHOW_VALUE; -- while ((opt = util_getopt_long()) != EOF) { -- switch (opt) { -- case_USAGE_COMMON_FLAGS -+ for (;;) { -+ int c = getopt(argc, argv, "d:hlpt:"); -+ if (c == -1) -+ break; -+ -+ switch (c) { -+ case 'h': -+ case '?': -+ usage(NULL); - - case 't': - if (utilfdt_decode_type(optarg, &disp.type, - &disp.size)) -- usage("invalid type string"); -+ usage("Invalid type string"); - break; - - case 'p': -@@ -341,7 +347,7 @@ int main(int argc, char *argv[]) - if (optind < argc) - filename = argv[optind++]; - if (!filename) -- usage("missing filename"); -+ usage("Missing filename"); - - argv += optind; - argc -= optind; -@@ -352,7 +358,7 @@ int main(int argc, char *argv[]) - - /* Check for node, property arguments */ - if (args_per_step == 2 && (argc % 2)) -- usage("must have an even number of arguments"); -+ usage("Must have an even number of arguments"); - - if (do_fdtget(&disp, filename, argv, argc, args_per_step)) - return 1; -diff --git a/scripts/dtc/fdtput.c b/scripts/dtc/fdtput.c -index 2a8d67447..f2197f519 100644 ---- a/scripts/dtc/fdtput.c -+++ b/scripts/dtc/fdtput.c -@@ -96,7 +96,12 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count, - /* enlarge our value buffer by a suitable margin if needed */ - if (upto + len > value_size) { - value_size = (upto + len) + 500; -- value = xrealloc(value, value_size); -+ value = realloc(value, value_size); -+ if (!value) { -+ fprintf(stderr, "Out of mmory: cannot alloc " -+ "%d bytes\n", value_size); -+ return -1; -+ } - } - - ptr = value + upto; -@@ -126,59 +131,19 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count, - return 0; - } - --#define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) -- --static char *_realloc_fdt(char *fdt, int delta) --{ -- int new_sz = fdt_totalsize(fdt) + delta; -- fdt = xrealloc(fdt, new_sz); -- fdt_open_into(fdt, fdt, new_sz); -- return fdt; --} -- --static char *realloc_node(char *fdt, const char *name) --{ -- int delta; -- /* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */ -- delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1) -- + FDT_TAGSIZE; -- return _realloc_fdt(fdt, delta); --} -- --static char *realloc_property(char *fdt, int nodeoffset, -- const char *name, int newlen) --{ -- int delta = 0; -- int oldlen = 0; -- -- if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) -- /* strings + property header */ -- delta = sizeof(struct fdt_property) + strlen(name) + 1; -- -- if (newlen > oldlen) -- /* actual value in off_struct */ -- delta += ALIGN(newlen) - ALIGN(oldlen); -- -- return _realloc_fdt(fdt, delta); --} -- --static int store_key_value(char **blob, const char *node_name, -+static int store_key_value(void *blob, const char *node_name, - const char *property, const char *buf, int len) - { - int node; - int err; - -- node = fdt_path_offset(*blob, node_name); -+ node = fdt_path_offset(blob, node_name); - if (node < 0) { - report_error(node_name, -1, node); - return -1; - } - -- err = fdt_setprop(*blob, node, property, buf, len); -- if (err == -FDT_ERR_NOSPACE) { -- *blob = realloc_property(*blob, node, property, len); -- err = fdt_setprop(*blob, node, property, buf, len); -- } -+ err = fdt_setprop(blob, node, property, buf, len); - if (err) { - report_error(property, -1, err); - return -1; -@@ -196,7 +161,7 @@ static int store_key_value(char **blob, const char *node_name, - * @param in_path Path to process - * @return 0 if ok, -1 on error - */ --static int create_paths(char **blob, const char *in_path) -+static int create_paths(void *blob, const char *in_path) - { - const char *path = in_path; - const char *sep; -@@ -212,11 +177,10 @@ static int create_paths(char **blob, const char *in_path) - if (!sep) - sep = path + strlen(path); - -- node = fdt_subnode_offset_namelen(*blob, offset, path, -+ node = fdt_subnode_offset_namelen(blob, offset, path, - sep - path); - if (node == -FDT_ERR_NOTFOUND) { -- *blob = realloc_node(*blob, path); -- node = fdt_add_subnode_namelen(*blob, offset, path, -+ node = fdt_add_subnode_namelen(blob, offset, path, - sep - path); - } - if (node < 0) { -@@ -239,7 +203,7 @@ static int create_paths(char **blob, const char *in_path) - * @param node_name Name of node to create - * @return new node offset if found, or -1 on failure - */ --static int create_node(char **blob, const char *node_name) -+static int create_node(void *blob, const char *node_name) - { - int node = 0; - char *p; -@@ -251,17 +215,15 @@ static int create_node(char **blob, const char *node_name) - } - *p = '\0'; - -- *blob = realloc_node(*blob, p + 1); -- - if (p > node_name) { -- node = fdt_path_offset(*blob, node_name); -+ node = fdt_path_offset(blob, node_name); - if (node < 0) { - report_error(node_name, -1, node); - return -1; - } - } - -- node = fdt_add_subnode(*blob, node, p + 1); -+ node = fdt_add_subnode(blob, node, p + 1); - if (node < 0) { - report_error(p + 1, -1, node); - return -1; -@@ -288,64 +250,66 @@ static int do_fdtput(struct display_info *disp, const char *filename, - * store them into the property. - */ - assert(arg_count >= 2); -- if (disp->auto_path && create_paths(&blob, *arg)) -+ if (disp->auto_path && create_paths(blob, *arg)) - return -1; - if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) || -- store_key_value(&blob, *arg, arg[1], value, len)) -+ store_key_value(blob, *arg, arg[1], value, len)) - ret = -1; - break; - case OPER_CREATE_NODE: - for (; ret >= 0 && arg_count--; arg++) { - if (disp->auto_path) -- ret = create_paths(&blob, *arg); -+ ret = create_paths(blob, *arg); - else -- ret = create_node(&blob, *arg); -+ ret = create_node(blob, *arg); - } - break; - } -- if (ret >= 0) { -- fdt_pack(blob); -+ if (ret >= 0) - ret = utilfdt_write(filename, blob); -- } - - free(blob); - return ret; - } - --/* Usage related data. */ --static const char usage_synopsis[] = -- "write a property value to a device tree\n" -- " fdtput
[...]\n" -- " fdtput -c
[...]\n" -+static const char *usage_msg = -+ "fdtput - write a property value to a device tree\n" - "\n" - "The command line arguments are joined together into a single value.\n" -+ "\n" -+ "Usage:\n" -+ " fdtput
[...]\n" -+ " fdtput -c
[...]\n" -+ "Options:\n" -+ "\t-c\t\tCreate nodes if they don't already exist\n" -+ "\t-p\t\tAutomatically create nodes as needed for the node path\n" -+ "\t-t \tType of data\n" -+ "\t-v\t\tVerbose: display each value decoded from command line\n" -+ "\t-h\t\tPrint this help\n\n" - USAGE_TYPE_MSG; --static const char usage_short_opts[] = "cpt:v" USAGE_COMMON_SHORT_OPTS; --static struct option const usage_long_opts[] = { -- {"create", no_argument, NULL, 'c'}, -- {"auto-path", no_argument, NULL, 'p'}, -- {"type", a_argument, NULL, 't'}, -- {"verbose", no_argument, NULL, 'v'}, -- USAGE_COMMON_LONG_OPTS, --}; --static const char * const usage_opts_help[] = { -- "Create nodes if they don't already exist", -- "Automatically create nodes as needed for the node path", -- "Type of data", -- "Display each value decoded from command line", -- USAGE_COMMON_OPTS_HELP --}; -+ -+static void usage(const char *msg) -+{ -+ if (msg) -+ fprintf(stderr, "Error: %s\n\n", msg); -+ -+ fprintf(stderr, "%s", usage_msg); -+ exit(2); -+} - - int main(int argc, char *argv[]) - { -- int opt; - struct display_info disp; - char *filename = NULL; - - memset(&disp, '\0', sizeof(disp)); - disp.size = -1; - disp.oper = OPER_WRITE_PROP; -- while ((opt = util_getopt_long()) != EOF) { -+ for (;;) { -+ int c = getopt(argc, argv, "chpt:v"); -+ if (c == -1) -+ break; -+ - /* - * TODO: add options to: - * - delete property -@@ -353,13 +317,15 @@ int main(int argc, char *argv[]) - * - rename node - * - pack fdt before writing - * - set amount of free space when writing -+ * - expand fdt if value doesn't fit - */ -- switch (opt) { -- case_USAGE_COMMON_FLAGS -- -+ switch (c) { - case 'c': - disp.oper = OPER_CREATE_NODE; - break; -+ case 'h': -+ case '?': -+ usage(NULL); - case 'p': - disp.auto_path = 1; - break; -@@ -378,16 +344,16 @@ int main(int argc, char *argv[]) - if (optind < argc) - filename = argv[optind++]; - if (!filename) -- usage("missing filename"); -+ usage("Missing filename"); - - argv += optind; - argc -= optind; - - if (disp.oper == OPER_WRITE_PROP) { - if (argc < 1) -- usage("missing node"); -+ usage("Missing node"); - if (argc < 2) -- usage("missing property"); -+ usage("Missing property"); - } - - if (do_fdtput(&disp, filename, argv, argc)) -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index bd99fa2d3..8d268fb78 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -49,7 +49,7 @@ static struct version_info { - - struct emitter { - void (*cell)(void *, cell_t); -- void (*string)(void *, char *, int); -+ void (*string)(void *, const char *, int); - void (*align)(void *, int); - void (*data)(void *, struct data); - void (*beginnode)(void *, struct label *labels); -@@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val) - *dtbuf = data_append_cell(*dtbuf, val); - } - --static void bin_emit_string(void *e, char *str, int len) -+static void bin_emit_string(void *e, const char *str, int len) - { - struct data *dtbuf = e; - -@@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val) - (val >> 8) & 0xff, val & 0xff); - } - --static void asm_emit_string(void *e, char *str, int len) -+static void asm_emit_string(void *e, const char *str, int len) - { - FILE *f = e; -- char c = 0; - -- if (len != 0) { -- /* XXX: ewww */ -- c = str[len]; -- str[len] = '\0'; -- } -- -- fprintf(f, "\t.string\t\"%s\"\n", str); -- -- if (len != 0) { -- str[len] = c; -- } -+ if (len != 0) -+ fprintf(f, "\t.string\t\"%.*s\"\n", len, str); -+ else -+ fprintf(f, "\t.string\t\"%s\"\n", str); - } - - static void asm_emit_align(void *e, int a) -@@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d) - emit_offset_label(f, m->ref, m->offset); - - while ((d.len - off) >= sizeof(uint32_t)) { -- asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); -+ asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); - off += sizeof(uint32_t); - } - -@@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, - { - struct reserve_info *re; - struct data d = empty_data; -- static struct fdt_reserve_entry null_re = {0,0}; - int j; - - for (re = reservelist; re; re = re->next) { -- d = data_append_re(d, &re->re); -+ d = data_append_re(d, re->address, re->size); - } - /* - * Add additional reserved slots if the user asked for them. - */ - for (j = 0; j < reservenum; j++) { -- d = data_append_re(d, &null_re); -+ d = data_append_re(d, 0, 0); - } - - return d; -@@ -366,7 +357,7 @@ static void make_fdt_header(struct fdt_header *fdt, - fdt->size_dt_struct = cpu_to_fdt32(dtsize); - } - --void dt_to_blob(FILE *f, struct boot_info *bi, int version) -+void dt_to_blob(FILE *f, struct dt_info *dti, int version) - { - struct version_info *vi = NULL; - int i; -@@ -384,29 +375,36 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) - if (!vi) - die("Unknown device tree blob version %d\n", version); - -- flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi); -+ flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); - bin_emit_cell(&dtbuf, FDT_END); - -- reservebuf = flatten_reserve_list(bi->reservelist, vi); -+ reservebuf = flatten_reserve_list(dti->reservelist, vi); - - /* Make header */ - make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, -- bi->boot_cpuid_phys); -+ dti->boot_cpuid_phys); - - /* - * If the user asked for more space than is used, adjust the totalsize. - */ - if (minsize > 0) { - padlen = minsize - fdt32_to_cpu(fdt.totalsize); -- if ((padlen < 0) && (quiet < 1)) -- fprintf(stderr, -- "Warning: blob size %d >= minimum size %d\n", -- fdt32_to_cpu(fdt.totalsize), minsize); -+ if (padlen < 0) { -+ padlen = 0; -+ if (quiet < 1) -+ fprintf(stderr, -+ "Warning: blob size %d >= minimum size %d\n", -+ fdt32_to_cpu(fdt.totalsize), minsize); -+ } - } - - if (padsize > 0) - padlen = padsize; - -+ if (alignsize > 0) -+ padlen = ALIGN(fdt32_to_cpu(fdt.totalsize) + padlen, alignsize) -+ - fdt32_to_cpu(fdt.totalsize); -+ - if (padlen > 0) { - int tsize = fdt32_to_cpu(fdt.totalsize); - tsize += padlen; -@@ -460,7 +458,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) - } - } - --void dt_to_asm(FILE *f, struct boot_info *bi, int version) -+void dt_to_asm(FILE *f, struct dt_info *dti, int version) - { - struct version_info *vi = NULL; - int i; -@@ -500,7 +498,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - - if (vi->flags & FTF_BOOTCPUID) { - fprintf(f, "\t/* boot_cpuid_phys */\n"); -- asm_emit_cell(f, bi->boot_cpuid_phys); -+ asm_emit_cell(f, dti->boot_cpuid_phys); - } - - if (vi->flags & FTF_STRTABSIZE) { -@@ -530,18 +528,18 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - * Use .long on high and low halfs of u64s to avoid .quad - * as it appears .quad isn't available in some assemblers. - */ -- for (re = bi->reservelist; re; re = re->next) { -+ for (re = dti->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) { - fprintf(f, "\t.globl\t%s\n", l->label); - fprintf(f, "%s:\n", l->label); - } -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32)); - ASM_EMIT_BELONG(f, "0x%08x", -- (unsigned int)(re->re.address & 0xffffffff)); -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); -+ (unsigned int)(re->address & 0xffffffff)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff)); - } - for (i = 0; i < reservenum; i++) { - fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); -@@ -550,7 +548,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); - - emit_label(f, symprefix, "struct_start"); -- flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); -+ flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi); - - fprintf(f, "\t/* FDT_END */\n"); - asm_emit_cell(f, FDT_END); -@@ -572,6 +570,8 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - if (padsize > 0) { - fprintf(f, "\t.space\t%d, 0\n", padsize); - } -+ if (alignsize > 0) -+ asm_emit_align(f, alignsize); - emit_label(f, symprefix, "blob_abs_end"); - - data_free(strbuf); -@@ -600,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) - - static uint32_t flat_read_word(struct inbuf *inb) - { -- uint32_t val; -+ fdt32_t val; - - assert(((inb->ptr - inb->base) % sizeof(val)) == 0); - -@@ -709,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) - * First pass, count entries. - */ - while (1) { -+ uint64_t address, size; -+ - flat_read_chunk(inb, &re, sizeof(re)); -- re.address = fdt64_to_cpu(re.address); -- re.size = fdt64_to_cpu(re.size); -- if (re.size == 0) -+ address = fdt64_to_cpu(re.address); -+ size = fdt64_to_cpu(re.size); -+ if (size == 0) - break; - -- new = build_reserve_entry(re.address, re.size); -+ new = build_reserve_entry(address, size); - reservelist = add_reserve_entry(reservelist, new); - } - -@@ -729,7 +731,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) - - plen = strlen(ppath); - -- if (!strneq(ppath, cpath, plen)) -+ if (!strstarts(cpath, ppath)) - die("Path \"%s\" is not valid as a child of \"%s\"\n", - cpath, ppath); - -@@ -797,13 +799,18 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, - } - } while (val != FDT_END_NODE); - -+ if (node->name != flatname) { -+ free(flatname); -+ } -+ - return node; - } - - --struct boot_info *dt_from_blob(const char *fname) -+struct dt_info *dt_from_blob(const char *fname) - { - FILE *f; -+ fdt32_t magic_buf, totalsize_buf; - uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; - uint32_t off_dt, off_str, off_mem_rsvmap; - int rc; -@@ -820,7 +827,7 @@ struct boot_info *dt_from_blob(const char *fname) - - f = srcfile_relative_open(fname, NULL); - -- rc = fread(&magic, sizeof(magic), 1, f); -+ rc = fread(&magic_buf, sizeof(magic_buf), 1, f); - if (ferror(f)) - die("Error reading DT blob magic number: %s\n", - strerror(errno)); -@@ -831,11 +838,11 @@ struct boot_info *dt_from_blob(const char *fname) - die("Mysterious short read reading magic number\n"); - } - -- magic = fdt32_to_cpu(magic); -+ magic = fdt32_to_cpu(magic_buf); - if (magic != FDT_MAGIC) - die("Blob has incorrect magic number\n"); - -- rc = fread(&totalsize, sizeof(totalsize), 1, f); -+ rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f); - if (ferror(f)) - die("Error reading DT blob size: %s\n", strerror(errno)); - if (rc < 1) { -@@ -845,7 +852,7 @@ struct boot_info *dt_from_blob(const char *fname) - die("Mysterious short read reading blob size\n"); - } - -- totalsize = fdt32_to_cpu(totalsize); -+ totalsize = fdt32_to_cpu(totalsize_buf); - if (totalsize < FDT_V1_SIZE) - die("DT blob size (%d) is too small\n", totalsize); - -@@ -889,7 +896,7 @@ struct boot_info *dt_from_blob(const char *fname) - - if (version >= 3) { - uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings); -- if (off_str+size_str > totalsize) -+ if ((off_str+size_str < off_str) || (off_str+size_str > totalsize)) - die("String table extends past total size\n"); - inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); - } else { -@@ -898,7 +905,7 @@ struct boot_info *dt_from_blob(const char *fname) - - if (version >= 17) { - size_dt = fdt32_to_cpu(fdt->size_dt_struct); -- if (off_dt+size_dt > totalsize) -+ if ((off_dt+size_dt < off_dt) || (off_dt+size_dt > totalsize)) - die("Structure block extends past total size\n"); - } - -@@ -929,5 +936,5 @@ struct boot_info *dt_from_blob(const char *fname) - - fclose(f); - -- return build_boot_info(reservelist, tree, boot_cpuid_phys); -+ return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys); - } -diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c -index 6d1beec95..ae7d06c3c 100644 ---- a/scripts/dtc/fstree.c -+++ b/scripts/dtc/fstree.c -@@ -79,13 +79,12 @@ static struct node *read_fstree(const char *dirname) - return tree; - } - --struct boot_info *dt_from_fs(const char *dirname) -+struct dt_info *dt_from_fs(const char *dirname) - { - struct node *tree; - - tree = read_fstree(dirname); - tree = name_node(tree, ""); - -- return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); -+ return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree)); - } -- -diff --git a/scripts/dtc/libfdt.h b/scripts/dtc/libfdt.h -index 32d52276d..1e27780e1 100644 ---- a/scripts/dtc/libfdt.h -+++ b/scripts/dtc/libfdt.h -@@ -1,5 +1,5 @@ --#ifndef _LIBFDT_H --#define _LIBFDT_H -+#ifndef LIBFDT_H -+#define LIBFDT_H - /* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. -@@ -51,17 +51,17 @@ - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - --#include --#include -+#include "libfdt_env.h" -+#include "fdt.h" - --#define FDT_FIRST_SUPPORTED_VERSION 0x10 -+#define FDT_FIRST_SUPPORTED_VERSION 0x02 - #define FDT_LAST_SUPPORTED_VERSION 0x11 - - /* Error codes: informative error codes */ - #define FDT_ERR_NOTFOUND 1 - /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ - #define FDT_ERR_EXISTS 2 -- /* FDT_ERR_EXISTS: Attemped to create a node or property which -+ /* FDT_ERR_EXISTS: Attempted to create a node or property which - * already exists */ - #define FDT_ERR_NOSPACE 3 - /* FDT_ERR_NOSPACE: Operation needed to expand the device -@@ -79,8 +79,10 @@ - * (e.g. missing a leading / for a function which requires an - * absolute path) */ - #define FDT_ERR_BADPHANDLE 6 -- /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle -- * value. phandle values of 0 and -1 are not permitted. */ -+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. -+ * This can be caused either by an invalid phandle property -+ * length, or the phandle value was either 0 or -1, which are -+ * not permitted. */ - #define FDT_ERR_BADSTATE 7 - /* FDT_ERR_BADSTATE: Function was passed an incomplete device - * tree created by the sequential-write functions, which is -@@ -121,13 +123,29 @@ - /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells - * or similar property with a bad format or value */ - --#define FDT_ERR_MAX 14 -+#define FDT_ERR_BADVALUE 15 -+ /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected -+ * value. For example: a property expected to contain a string list -+ * is not NUL-terminated within the length of its value. */ -+ -+#define FDT_ERR_BADOVERLAY 16 -+ /* FDT_ERR_BADOVERLAY: The device tree overlay, while -+ * correctly structured, cannot be applied due to some -+ * unexpected or missing value, property or node. */ -+ -+#define FDT_ERR_NOPHANDLES 17 -+ /* FDT_ERR_NOPHANDLES: The device tree doesn't have any -+ * phandle available anymore without causing an overflow */ -+ -+#define FDT_ERR_MAX 17 - - /**********************************************************************/ - /* Low-level functions (you probably don't need these) */ - /**********************************************************************/ - -+#ifndef SWIG /* This function is not useful in Python */ - const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); -+#endif - static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) - { - return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); -@@ -163,40 +181,67 @@ int fdt_first_subnode(const void *fdt, int offset); - */ - int fdt_next_subnode(const void *fdt, int offset); - -+/** -+ * fdt_for_each_subnode - iterate over all subnodes of a parent -+ * -+ * @node: child node (int, lvalue) -+ * @fdt: FDT blob (const void *) -+ * @parent: parent node (int) -+ * -+ * This is actually a wrapper around a for loop and would be used like so: -+ * -+ * fdt_for_each_subnode(node, fdt, parent) { -+ * Use node -+ * ... -+ * } -+ * -+ * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { -+ * Error handling -+ * } -+ * -+ * Note that this is implemented as a macro and @node is used as -+ * iterator in the loop. The parent variable be constant or even a -+ * literal. -+ * -+ */ -+#define fdt_for_each_subnode(node, fdt, parent) \ -+ for (node = fdt_first_subnode(fdt, parent); \ -+ node >= 0; \ -+ node = fdt_next_subnode(fdt, node)) -+ - /**********************************************************************/ - /* General functions */ - /**********************************************************************/ -- - #define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) --#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) -+#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) - #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) - #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) - #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) - #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) - #define fdt_version(fdt) (fdt_get_header(fdt, version)) --#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) --#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) --#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) -+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) - #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) - --#define __fdt_set_hdr(name) \ -+#define fdt_set_hdr_(name) \ - static inline void fdt_set_##name(void *fdt, uint32_t val) \ - { \ -- struct fdt_header *fdth = (struct fdt_header*)fdt; \ -+ struct fdt_header *fdth = (struct fdt_header *)fdt; \ - fdth->name = cpu_to_fdt32(val); \ - } --__fdt_set_hdr(magic); --__fdt_set_hdr(totalsize); --__fdt_set_hdr(off_dt_struct); --__fdt_set_hdr(off_dt_strings); --__fdt_set_hdr(off_mem_rsvmap); --__fdt_set_hdr(version); --__fdt_set_hdr(last_comp_version); --__fdt_set_hdr(boot_cpuid_phys); --__fdt_set_hdr(size_dt_strings); --__fdt_set_hdr(size_dt_struct); --#undef __fdt_set_hdr -+fdt_set_hdr_(magic); -+fdt_set_hdr_(totalsize); -+fdt_set_hdr_(off_dt_struct); -+fdt_set_hdr_(off_dt_strings); -+fdt_set_hdr_(off_mem_rsvmap); -+fdt_set_hdr_(version); -+fdt_set_hdr_(last_comp_version); -+fdt_set_hdr_(boot_cpuid_phys); -+fdt_set_hdr_(size_dt_strings); -+fdt_set_hdr_(size_dt_struct); -+#undef fdt_set_hdr_ - - /** - * fdt_check_header - sanity check a device tree or possible device tree -@@ -253,6 +298,21 @@ int fdt_move(const void *fdt, void *buf, int bufsize); - */ - const char *fdt_string(const void *fdt, int stroffset); - -+/** -+ * fdt_get_max_phandle - retrieves the highest phandle in a tree -+ * @fdt: pointer to the device tree blob -+ * -+ * fdt_get_max_phandle retrieves the highest phandle in the given -+ * device tree. This will ignore badly formatted phandles, or phandles -+ * with a value of 0 or -1. -+ * -+ * returns: -+ * the highest phandle on success -+ * 0, if no phandle was found in the device tree -+ * -1, if an error occurred -+ */ -+uint32_t fdt_get_max_phandle(const void *fdt); -+ - /** - * fdt_num_mem_rsv - retrieve the number of memory reserve map entries - * @fdt: pointer to the device tree blob -@@ -295,8 +355,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); - * useful for finding subnodes based on a portion of a larger string, - * such as a full path. - */ -+#ifndef SWIG /* Not available in Python */ - int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - const char *name, int namelen); -+#endif - /** - * fdt_subnode_offset - find a subnode of a given node - * @fdt: pointer to the device tree blob -@@ -313,8 +375,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - * returns: - * structure block offset of the requested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -- * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag -+ * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, -@@ -322,6 +385,19 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - */ - int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); - -+/** -+ * fdt_path_offset_namelen - find a tree node by its full path -+ * @fdt: pointer to the device tree blob -+ * @path: full path of the node to locate -+ * @namelen: number of characters of path to consider -+ * -+ * Identical to fdt_path_offset(), but only consider the first namelen -+ * characters of path as the path name. -+ */ -+#ifndef SWIG /* Not available in Python */ -+int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); -+#endif -+ - /** - * fdt_path_offset - find a tree node by its full path - * @fdt: pointer to the device tree blob -@@ -335,7 +411,8 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); - * address). - * - * returns: -- * structure block offset of the node with the requested path (>=0), on success -+ * structure block offset of the node with the requested path (>=0), on -+ * success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid - * -FDT_ERR_NOTFOUND, if the requested node does not exist - * -FDT_ERR_BADMAGIC, -@@ -359,10 +436,12 @@ int fdt_path_offset(const void *fdt, const char *path); - * - * returns: - * pointer to the node's name, on success -- * If lenp is non-NULL, *lenp contains the length of that name (>=0) -+ * If lenp is non-NULL, *lenp contains the length of that name -+ * (>=0) - * NULL, on error - * if lenp is non-NULL *lenp contains an error code (<0): -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings -@@ -410,6 +489,33 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset); - */ - int fdt_next_property_offset(const void *fdt, int offset); - -+/** -+ * fdt_for_each_property_offset - iterate over all properties of a node -+ * -+ * @property_offset: property offset (int, lvalue) -+ * @fdt: FDT blob (const void *) -+ * @node: node offset (int) -+ * -+ * This is actually a wrapper around a for loop and would be used like so: -+ * -+ * fdt_for_each_property_offset(property, fdt, node) { -+ * Use property -+ * ... -+ * } -+ * -+ * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { -+ * Error handling -+ * } -+ * -+ * Note that this is implemented as a macro and property is used as -+ * iterator in the loop. The node variable can be constant or even a -+ * literal. -+ */ -+#define fdt_for_each_property_offset(property, fdt, node) \ -+ for (property = fdt_first_property_offset(fdt, node); \ -+ property >= 0; \ -+ property = fdt_next_property_offset(fdt, property)) -+ - /** - * fdt_get_property_by_offset - retrieve the property at a given offset - * @fdt: pointer to the device tree blob -@@ -421,6 +527,9 @@ int fdt_next_property_offset(const void *fdt, int offset); - * offset. If lenp is non-NULL, the length of the property value is - * also returned, in the integer pointed to by lenp. - * -+ * Note that this code only works on device tree versions >= 16. fdt_getprop() -+ * works on all versions. -+ * - * returns: - * pointer to the structure representing the property - * if lenp is non-NULL, *lenp contains the length of the property -@@ -446,13 +555,15 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - * @namelen: number of characters of name to consider - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * -- * Identical to fdt_get_property_namelen(), but only examine the first -- * namelen characters of name for matching the property name. -+ * Identical to fdt_get_property(), but only examine the first namelen -+ * characters of name for matching the property name. - */ -+#ifndef SWIG /* Not available in Python */ - const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int nodeoffset, - const char *name, - int namelen, int *lenp); -+#endif - - /** - * fdt_get_property - find a given property in a given node -@@ -474,7 +585,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -522,8 +634,10 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -+#ifndef SWIG /* This function is not useful in Python */ - const void *fdt_getprop_by_offset(const void *fdt, int offset, - const char **namep, int *lenp); -+#endif - - /** - * fdt_getprop_namelen - get property value based on substring -@@ -536,8 +650,17 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, - * Identical to fdt_getprop(), but only examine the first namelen - * characters of name for matching the property name. - */ -+#ifndef SWIG /* Not available in Python */ - const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp); -+static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ int *lenp) -+{ -+ return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, -+ namelen, lenp); -+} -+#endif - - /** - * fdt_getprop - retrieve the value of a given property -@@ -559,7 +682,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -597,11 +721,13 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); - * Identical to fdt_get_alias(), but only examine the first namelen - * characters of name for matching the alias name. - */ -+#ifndef SWIG /* Not available in Python */ - const char *fdt_get_alias_namelen(const void *fdt, - const char *name, int namelen); -+#endif - - /** -- * fdt_get_alias - retreive the path referenced by a given alias -+ * fdt_get_alias - retrieve the path referenced by a given alias - * @fdt: pointer to the device tree blob - * @name: name of the alias th look up - * -@@ -631,7 +757,7 @@ const char *fdt_get_alias(const void *fdt, const char *name); - * 0, on success - * buf contains the absolute path of the node at - * nodeoffset, as a NUL-terminated string. -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) - * characters and will not fit in the given buffer. - * -FDT_ERR_BADMAGIC, -@@ -661,11 +787,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); - * structure from the start to nodeoffset. - * - * returns: -- - * structure block offset of the node at node offset's ancestor - * of depth supernodedepth (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag --* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of -+ * nodeoffset - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -687,7 +813,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - * - * returns: - * depth of the node at nodeoffset (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -710,7 +836,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); - * returns: - * structure block offset of the parent of the node at nodeoffset - * (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -750,7 +876,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset); - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -797,7 +923,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); - * 1, if the node has a 'compatible' property, but it does not list - * the given string - * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property -- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -834,7 +960,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -857,6 +983,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, - */ - int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); - -+/** -+ * fdt_stringlist_count - count the number of strings in a string list -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of a tree node -+ * @property: name of the property containing the string list -+ * @return: -+ * the number of strings in the given property -+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated -+ * -FDT_ERR_NOTFOUND if the property does not exist -+ */ -+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); -+ -+/** -+ * fdt_stringlist_search - find a string in a string list and return its index -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of a tree node -+ * @property: name of the property containing the string list -+ * @string: string to look up in the string list -+ * -+ * Note that it is possible for this function to succeed on property values -+ * that are not NUL-terminated. That's because the function will stop after -+ * finding the first occurrence of @string. This can for example happen with -+ * small-valued cell properties, such as #address-cells, when searching for -+ * the empty string. -+ * -+ * @return: -+ * the index of the string in the list of strings -+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated -+ * -FDT_ERR_NOTFOUND if the property does not exist or does not contain -+ * the given string -+ */ -+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, -+ const char *string); -+ -+/** -+ * fdt_stringlist_get() - obtain the string at a given index in a string list -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of a tree node -+ * @property: name of the property containing the string list -+ * @index: index of the string to return -+ * @lenp: return location for the string length or an error code on failure -+ * -+ * Note that this will successfully extract strings from properties with -+ * non-NUL-terminated values. For example on small-valued cell properties -+ * this function will return the empty string. -+ * -+ * If non-NULL, the length of the string (on success) or a negative error-code -+ * (on failure) will be stored in the integer pointer to by lenp. -+ * -+ * @return: -+ * A pointer to the string at the given index in the string list or NULL on -+ * failure. On success the length of the string will be stored in the memory -+ * location pointed to by the lenp parameter, if non-NULL. On failure one of -+ * the following negative error codes will be returned in the lenp parameter -+ * (if non-NULL): -+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated -+ * -FDT_ERR_NOTFOUND if the property does not exist -+ */ -+const char *fdt_stringlist_get(const void *fdt, int nodeoffset, -+ const char *property, int index, -+ int *lenp); -+ - /**********************************************************************/ - /* Read-only functions (addressing related) */ - /**********************************************************************/ -@@ -882,7 +1070,8 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #address-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -902,7 +1091,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #size-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -916,6 +1106,29 @@ int fdt_size_cells(const void *fdt, int nodeoffset); - /* Write-in-place functions */ - /**********************************************************************/ - -+/** -+ * fdt_setprop_inplace_namelen_partial - change a property's value, -+ * but not its size -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @namelen: number of characters of name to consider -+ * @idx: index of the property to change in the array -+ * @val: pointer to data to replace the property value with -+ * @len: length of the property value -+ * -+ * Identical to fdt_setprop_inplace(), but modifies the given property -+ * starting from the given index, and using only the first characters -+ * of the name. It is useful when you want to manipulate only one value of -+ * an array and you have a string that doesn't end with \0. -+ */ -+#ifndef SWIG /* Not available in Python */ -+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ uint32_t idx, const void *val, -+ int len); -+#endif -+ - /** - * fdt_setprop_inplace - change a property's value, but not its size - * @fdt: pointer to the device tree blob -@@ -944,8 +1157,10 @@ int fdt_size_cells(const void *fdt, int nodeoffset); - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -+#ifndef SWIG /* Not available in Python */ - int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, - const void *val, int len); -+#endif - - /** - * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property -@@ -1102,6 +1317,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) - { - return fdt_property_u32(fdt, name, val); - } -+ -+/** -+ * fdt_property_placeholder - add a new property and return a ptr to its value -+ * -+ * @fdt: pointer to the device tree blob -+ * @name: name of property to add -+ * @len: length of property value in bytes -+ * @valp: returns a pointer to where where the value should be placed -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_NOSPACE, standard meanings -+ */ -+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); -+ - #define fdt_property_string(fdt, name, str) \ - fdt_property(fdt, name, str, strlen(str)+1) - int fdt_end_node(void *fdt); -@@ -1220,6 +1451,37 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name); - int fdt_setprop(void *fdt, int nodeoffset, const char *name, - const void *val, int len); - -+/** -+ * fdt_setprop_placeholder - allocate space for a property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @len: length of the property value -+ * @prop_data: return pointer to property data -+ * -+ * fdt_setprop_placeholer() allocates the named property in the given node. -+ * If the property exists it is resized. In either case a pointer to the -+ * property data is returned. -+ * -+ * This function may insert or delete data from the blob, and will -+ * therefore change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to -+ * contain the new property value -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, -+ int len, void **prop_data); -+ - /** - * fdt_setprop_u32 - set a property to a 32-bit integer - * @fdt: pointer to the device tree blob -@@ -1332,6 +1594,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, - #define fdt_setprop_string(fdt, nodeoffset, name, str) \ - fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) - -+ -+/** -+ * fdt_setprop_empty - set a property to an empty value -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * -+ * fdt_setprop_empty() sets the value of the named property in the -+ * given node to an empty (zero length) value, or creates a new empty -+ * property if it does not already exist. -+ * -+ * This function may insert or delete data from the blob, and will -+ * therefore change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to -+ * contain the new property value -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+#define fdt_setprop_empty(fdt, nodeoffset, name) \ -+ fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) -+ - /** - * fdt_appendprop - append to or create a property - * @fdt: pointer to the device tree blob -@@ -1509,8 +1801,10 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name); - * creating subnodes based on a portion of a larger string, such as a - * full path. - */ -+#ifndef SWIG /* Not available in Python */ - int fdt_add_subnode_namelen(void *fdt, int parentoffset, - const char *name, int namelen); -+#endif - - /** - * fdt_add_subnode - creates a new node -@@ -1526,9 +1820,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, - * change the offsets of some existing nodes. - - * returns: -- * structure block offset of the created nodeequested subnode (>=0), on success -+ * structure block offset of the created nodeequested subnode (>=0), on -+ * success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of - * the given name - * -FDT_ERR_NOSPACE, if there is insufficient free space in the -@@ -1566,10 +1862,41 @@ int fdt_add_subnode(void *fdt, int parentoffset, const char *name); - */ - int fdt_del_node(void *fdt, int nodeoffset); - -+/** -+ * fdt_overlay_apply - Applies a DT overlay on a base DT -+ * @fdt: pointer to the base device tree blob -+ * @fdto: pointer to the device tree overlay blob -+ * -+ * fdt_overlay_apply() will apply the given device tree overlay on the -+ * given base device tree. -+ * -+ * Expect the base device tree to be modified, even if the function -+ * returns an error. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there's not enough space in the base device tree -+ * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or -+ * properties in the base DT -+ * -FDT_ERR_BADPHANDLE, -+ * -FDT_ERR_BADOVERLAY, -+ * -FDT_ERR_NOPHANDLES, -+ * -FDT_ERR_INTERNAL, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADOFFSET, -+ * -FDT_ERR_BADPATH, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_overlay_apply(void *fdt, void *fdto); -+ - /**********************************************************************/ - /* Debugging / informational functions */ - /**********************************************************************/ - - const char *fdt_strerror(int errval); - --#endif /* _LIBFDT_H */ -+#endif /* LIBFDT_H */ -diff --git a/scripts/dtc/libfdt_env.h b/scripts/dtc/libfdt_env.h -index 9dea97dff..bd2474628 100644 ---- a/scripts/dtc/libfdt_env.h -+++ b/scripts/dtc/libfdt_env.h -@@ -1,5 +1,5 @@ --#ifndef _LIBFDT_ENV_H --#define _LIBFDT_ENV_H -+#ifndef LIBFDT_ENV_H -+#define LIBFDT_ENV_H - /* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. -@@ -54,19 +54,20 @@ - - #include - #include -+#include - #include - - #ifdef __CHECKER__ --#define __force __attribute__((force)) --#define __bitwise __attribute__((bitwise)) -+#define FDT_FORCE __attribute__((force)) -+#define FDT_BITWISE __attribute__((bitwise)) - #else --#define __force --#define __bitwise -+#define FDT_FORCE -+#define FDT_BITWISE - #endif - --typedef uint16_t __bitwise fdt16_t; --typedef uint32_t __bitwise fdt32_t; --typedef uint64_t __bitwise fdt64_t; -+typedef uint16_t FDT_BITWISE fdt16_t; -+typedef uint32_t FDT_BITWISE fdt32_t; -+typedef uint64_t FDT_BITWISE fdt64_t; - - #define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) - #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) -@@ -79,33 +80,60 @@ typedef uint64_t __bitwise fdt64_t; - - static inline uint16_t fdt16_to_cpu(fdt16_t x) - { -- return (__force uint16_t)CPU_TO_FDT16(x); -+ return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); - } - static inline fdt16_t cpu_to_fdt16(uint16_t x) - { -- return (__force fdt16_t)CPU_TO_FDT16(x); -+ return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); - } - - static inline uint32_t fdt32_to_cpu(fdt32_t x) - { -- return (__force uint32_t)CPU_TO_FDT32(x); -+ return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); - } - static inline fdt32_t cpu_to_fdt32(uint32_t x) - { -- return (__force fdt32_t)CPU_TO_FDT32(x); -+ return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); - } - - static inline uint64_t fdt64_to_cpu(fdt64_t x) - { -- return (__force uint64_t)CPU_TO_FDT64(x); -+ return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); - } - static inline fdt64_t cpu_to_fdt64(uint64_t x) - { -- return (__force fdt64_t)CPU_TO_FDT64(x); -+ return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x); - } - #undef CPU_TO_FDT64 - #undef CPU_TO_FDT32 - #undef CPU_TO_FDT16 - #undef EXTRACT_BYTE - --#endif /* _LIBFDT_ENV_H */ -+#ifdef __APPLE__ -+#include -+ -+/* strnlen() is not available on Mac OS < 10.7 */ -+# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \ -+ MAC_OS_X_VERSION_10_7) -+ -+#define strnlen fdt_strnlen -+ -+/* -+ * fdt_strnlen: returns the length of a string or max_count - which ever is -+ * smallest. -+ * Input 1 string: the string whose size is to be determined -+ * Input 2 max_count: the maximum value returned by this function -+ * Output: length of the string or max_count (the smallest of the two) -+ */ -+static inline size_t fdt_strnlen(const char *string, size_t max_count) -+{ -+ const char *p = memchr(string, 0, max_count); -+ return p ? p - string : max_count; -+} -+ -+#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < -+ MAC_OS_X_VERSION_10_7) */ -+ -+#endif /* __APPLE__ */ -+ -+#endif /* LIBFDT_ENV_H */ -diff --git a/scripts/dtc/libfdt_internal.h b/scripts/dtc/libfdt_internal.h -index 02cfa6fb6..7681e1922 100644 ---- a/scripts/dtc/libfdt_internal.h -+++ b/scripts/dtc/libfdt_internal.h -@@ -1,5 +1,5 @@ --#ifndef _LIBFDT_INTERNAL_H --#define _LIBFDT_INTERNAL_H -+#ifndef LIBFDT_INTERNAL_H -+#define LIBFDT_INTERNAL_H - /* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. -@@ -57,27 +57,27 @@ - - #define FDT_CHECK_HEADER(fdt) \ - { \ -- int __err; \ -- if ((__err = fdt_check_header(fdt)) != 0) \ -- return __err; \ -+ int err_; \ -+ if ((err_ = fdt_check_header(fdt)) != 0) \ -+ return err_; \ - } - --int _fdt_check_node_offset(const void *fdt, int offset); --int _fdt_check_prop_offset(const void *fdt, int offset); --const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); --int _fdt_node_end_offset(void *fdt, int nodeoffset); -+int fdt_check_node_offset_(const void *fdt, int offset); -+int fdt_check_prop_offset_(const void *fdt, int offset); -+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s); -+int fdt_node_end_offset_(void *fdt, int nodeoffset); - --static inline const void *_fdt_offset_ptr(const void *fdt, int offset) -+static inline const void *fdt_offset_ptr_(const void *fdt, int offset) - { - return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; - } - --static inline void *_fdt_offset_ptr_w(void *fdt, int offset) -+static inline void *fdt_offset_ptr_w_(void *fdt, int offset) - { -- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); -+ return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset); - } - --static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) -+static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n) - { - const struct fdt_reserve_entry *rsv_table = - (const struct fdt_reserve_entry *) -@@ -85,11 +85,11 @@ static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int - - return rsv_table + n; - } --static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) -+static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) - { -- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); -+ return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); - } - - #define FDT_SW_MAGIC (~FDT_MAGIC) - --#endif /* _LIBFDT_INTERNAL_H */ -+#endif /* LIBFDT_INTERNAL_H */ -diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c -index e229b8443..57b7db2ed 100644 ---- a/scripts/dtc/livetree.c -+++ b/scripts/dtc/livetree.c -@@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) - } - } - -- /* if no collision occured, add child to the old node. */ -+ /* if no collision occurred, add child to the old node. */ - if (new_child) - add_child(old_node, new_child); - } -@@ -216,6 +216,29 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) - return old_node; - } - -+struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) -+{ -+ static unsigned int next_orphan_fragment = 0; -+ struct node *node; -+ struct property *p; -+ struct data d = empty_data; -+ char *name; -+ -+ d = data_add_marker(d, REF_PHANDLE, ref); -+ d = data_append_integer(d, 0xffffffff, 32); -+ -+ p = build_property("target", d); -+ -+ xasprintf(&name, "fragment@%u", -+ next_orphan_fragment++); -+ name_node(new_node, "__overlay__"); -+ node = build_node(p, new_node); -+ name_node(node, name); -+ -+ add_child(dt, node); -+ return dt; -+} -+ - struct node *chain_node(struct node *first, struct node *list) - { - assert(first->next_sibling == NULL); -@@ -242,7 +265,7 @@ void delete_property_by_name(struct node *node, char *name) - struct property *prop = node->proplist; - - while (prop) { -- if (!strcmp(prop->name, name)) { -+ if (streq(prop->name, name)) { - delete_property(prop); - return; - } -@@ -275,7 +298,7 @@ void delete_node_by_name(struct node *parent, char *name) - struct node *node = parent->children; - - while (node) { -- if (!strcmp(node->name, name)) { -+ if (streq(node->name, name)) { - delete_node(node); - return; - } -@@ -296,14 +319,31 @@ void delete_node(struct node *node) - delete_labels(&node->labels); - } - -+void append_to_property(struct node *node, -+ char *name, const void *data, int len) -+{ -+ struct data d; -+ struct property *p; -+ -+ p = get_property(node, name); -+ if (p) { -+ d = data_append_data(p->val, data, len); -+ p->val = d; -+ } else { -+ d = data_append_data(empty_data, data, len); -+ p = build_property(name, d); -+ add_property(node, p); -+ } -+} -+ - struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) - { - struct reserve_info *new = xmalloc(sizeof(*new)); - - memset(new, 0, sizeof(*new)); - -- new->re.address = address; -- new->re.size = size; -+ new->address = address; -+ new->size = size; - - return new; - } -@@ -335,17 +375,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, - return list; - } - --struct boot_info *build_boot_info(struct reserve_info *reservelist, -- struct node *tree, uint32_t boot_cpuid_phys) -+struct dt_info *build_dt_info(unsigned int dtsflags, -+ struct reserve_info *reservelist, -+ struct node *tree, uint32_t boot_cpuid_phys) - { -- struct boot_info *bi; -+ struct dt_info *dti; - -- bi = xmalloc(sizeof(*bi)); -- bi->reservelist = reservelist; -- bi->dt = tree; -- bi->boot_cpuid_phys = boot_cpuid_phys; -+ dti = xmalloc(sizeof(*dti)); -+ dti->dtsflags = dtsflags; -+ dti->reservelist = reservelist; -+ dti->dt = tree; -+ dti->boot_cpuid_phys = boot_cpuid_phys; - -- return bi; -+ return dti; - } - - /* -@@ -374,7 +416,13 @@ struct property *get_property(struct node *node, const char *propname) - cell_t propval_cell(struct property *prop) - { - assert(prop->val.len == sizeof(cell_t)); -- return fdt32_to_cpu(*((cell_t *)prop->val.val)); -+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); -+} -+ -+cell_t propval_cell_n(struct property *prop, int n) -+{ -+ assert(prop->val.len / sizeof(cell_t) >= n); -+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); - } - - struct property *get_property_by_label(struct node *tree, const char *label, -@@ -459,7 +507,8 @@ struct node *get_node_by_path(struct node *tree, const char *path) - p = strchr(path, '/'); - - for_each_child(tree, child) { -- if (p && strneq(path, child->name, p-path)) -+ if (p && (strlen(child->name) == p-path) && -+ strprefixeq(path, p - path, child->name)) - return get_node_by_path(child, p+1); - else if (!p && streq(path, child->name)) - return child; -@@ -492,7 +541,10 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) - { - struct node *child, *node; - -- assert((phandle != 0) && (phandle != -1)); -+ if ((phandle == 0) || (phandle == -1)) { -+ assert(generate_fixups); -+ return NULL; -+ } - - if (tree->phandle == phandle) { - if (tree->deleted) -@@ -580,24 +632,24 @@ static int cmp_reserve_info(const void *ax, const void *bx) - a = *((const struct reserve_info * const *)ax); - b = *((const struct reserve_info * const *)bx); - -- if (a->re.address < b->re.address) -+ if (a->address < b->address) - return -1; -- else if (a->re.address > b->re.address) -+ else if (a->address > b->address) - return 1; -- else if (a->re.size < b->re.size) -+ else if (a->size < b->size) - return -1; -- else if (a->re.size > b->re.size) -+ else if (a->size > b->size) - return 1; - else - return 0; - } - --static void sort_reserve_entries(struct boot_info *bi) -+static void sort_reserve_entries(struct dt_info *dti) - { - struct reserve_info *ri, **tbl; - int n = 0, i = 0; - -- for (ri = bi->reservelist; -+ for (ri = dti->reservelist; - ri; - ri = ri->next) - n++; -@@ -607,14 +659,14 @@ static void sort_reserve_entries(struct boot_info *bi) - - tbl = xmalloc(n * sizeof(*tbl)); - -- for (ri = bi->reservelist; -+ for (ri = dti->reservelist; - ri; - ri = ri->next) - tbl[i++] = ri; - - qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); - -- bi->reservelist = tbl[0]; -+ dti->reservelist = tbl[0]; - for (i = 0; i < (n-1); i++) - tbl[i]->next = tbl[i+1]; - tbl[n-1]->next = NULL; -@@ -704,8 +756,258 @@ static void sort_node(struct node *node) - sort_node(c); - } - --void sort_tree(struct boot_info *bi) -+void sort_tree(struct dt_info *dti) -+{ -+ sort_reserve_entries(dti); -+ sort_node(dti->dt); -+} -+ -+/* utility helper to avoid code duplication */ -+static struct node *build_and_name_child_node(struct node *parent, char *name) -+{ -+ struct node *node; -+ -+ node = build_node(NULL, NULL); -+ name_node(node, xstrdup(name)); -+ add_child(parent, node); -+ -+ return node; -+} -+ -+static struct node *build_root_node(struct node *dt, char *name) -+{ -+ struct node *an; -+ -+ an = get_subnode(dt, name); -+ if (!an) -+ an = build_and_name_child_node(dt, name); -+ -+ if (!an) -+ die("Could not build root node /%s\n", name); -+ -+ return an; -+} -+ -+static bool any_label_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ -+ if (node->labels) -+ return true; -+ -+ for_each_child(node, c) -+ if (any_label_tree(dti, c)) -+ return true; -+ -+ return false; -+} -+ -+static void generate_label_tree_internal(struct dt_info *dti, -+ struct node *an, struct node *node, -+ bool allocph) - { -- sort_reserve_entries(bi); -- sort_node(bi->dt); -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *p; -+ struct label *l; -+ -+ /* if there are labels */ -+ if (node->labels) { -+ -+ /* now add the label in the node */ -+ for_each_label(node->labels, l) { -+ -+ /* check whether the label already exists */ -+ p = get_property(an, l->label); -+ if (p) { -+ fprintf(stderr, "WARNING: label %s already" -+ " exists in /%s", l->label, -+ an->name); -+ continue; -+ } -+ -+ /* insert it */ -+ p = build_property(l->label, -+ data_copy_mem(node->fullpath, -+ strlen(node->fullpath) + 1)); -+ add_property(an, p); -+ } -+ -+ /* force allocation of a phandle for this node */ -+ if (allocph) -+ (void)get_node_phandle(dt, node); -+ } -+ -+ for_each_child(node, c) -+ generate_label_tree_internal(dti, an, c, allocph); -+} -+ -+static bool any_fixup_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ if (!get_node_by_ref(dti->dt, m->ref)) -+ return true; -+ } -+ } -+ -+ for_each_child(node, c) { -+ if (any_fixup_tree(dti, c)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void add_fixup_entry(struct dt_info *dti, struct node *fn, -+ struct node *node, struct property *prop, -+ struct marker *m) -+{ -+ char *entry; -+ -+ /* m->ref can only be a REF_PHANDLE, but check anyway */ -+ assert(m->type == REF_PHANDLE); -+ -+ /* there shouldn't be any ':' in the arguments */ -+ if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) -+ die("arguments should not contain ':'\n"); -+ -+ xasprintf(&entry, "%s:%s:%u", -+ node->fullpath, prop->name, m->offset); -+ append_to_property(fn, m->ref, entry, strlen(entry) + 1); -+ -+ free(entry); -+} -+ -+static void generate_fixups_tree_internal(struct dt_info *dti, -+ struct node *fn, -+ struct node *node) -+{ -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ struct node *refnode; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ refnode = get_node_by_ref(dt, m->ref); -+ if (!refnode) -+ add_fixup_entry(dti, fn, node, prop, m); -+ } -+ } -+ -+ for_each_child(node, c) -+ generate_fixups_tree_internal(dti, fn, c); -+} -+ -+static bool any_local_fixup_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ if (get_node_by_ref(dti->dt, m->ref)) -+ return true; -+ } -+ } -+ -+ for_each_child(node, c) { -+ if (any_local_fixup_tree(dti, c)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void add_local_fixup_entry(struct dt_info *dti, -+ struct node *lfn, struct node *node, -+ struct property *prop, struct marker *m, -+ struct node *refnode) -+{ -+ struct node *wn, *nwn; /* local fixup node, walk node, new */ -+ fdt32_t value_32; -+ char **compp; -+ int i, depth; -+ -+ /* walk back retreiving depth */ -+ depth = 0; -+ for (wn = node; wn; wn = wn->parent) -+ depth++; -+ -+ /* allocate name array */ -+ compp = xmalloc(sizeof(*compp) * depth); -+ -+ /* store names in the array */ -+ for (wn = node, i = depth - 1; wn; wn = wn->parent, i--) -+ compp[i] = wn->name; -+ -+ /* walk the path components creating nodes if they don't exist */ -+ for (wn = lfn, i = 1; i < depth; i++, wn = nwn) { -+ /* if no node exists, create it */ -+ nwn = get_subnode(wn, compp[i]); -+ if (!nwn) -+ nwn = build_and_name_child_node(wn, compp[i]); -+ } -+ -+ free(compp); -+ -+ value_32 = cpu_to_fdt32(m->offset); -+ append_to_property(wn, prop->name, &value_32, sizeof(value_32)); -+} -+ -+static void generate_local_fixups_tree_internal(struct dt_info *dti, -+ struct node *lfn, -+ struct node *node) -+{ -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ struct node *refnode; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ refnode = get_node_by_ref(dt, m->ref); -+ if (refnode) -+ add_local_fixup_entry(dti, lfn, node, prop, m, refnode); -+ } -+ } -+ -+ for_each_child(node, c) -+ generate_local_fixups_tree_internal(dti, lfn, c); -+} -+ -+void generate_label_tree(struct dt_info *dti, char *name, bool allocph) -+{ -+ if (!any_label_tree(dti, dti->dt)) -+ return; -+ generate_label_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt, allocph); -+} -+ -+void generate_fixups_tree(struct dt_info *dti, char *name) -+{ -+ if (!any_fixup_tree(dti, dti->dt)) -+ return; -+ generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt); -+} -+ -+void generate_local_fixups_tree(struct dt_info *dti, char *name) -+{ -+ if (!any_local_fixup_tree(dti, dti->dt)) -+ return; -+ generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt); - } -diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c -index f534c22a8..cb6ed0e3e 100644 ---- a/scripts/dtc/srcpos.c -+++ b/scripts/dtc/srcpos.c -@@ -209,8 +209,6 @@ struct srcpos srcpos_empty = { - .file = NULL, - }; - --#define TAB_SIZE 8 -- - void srcpos_update(struct srcpos *pos, const char *text, int len) - { - int i; -@@ -224,9 +222,6 @@ void srcpos_update(struct srcpos *pos, const char *text, int len) - if (text[i] == '\n') { - current_srcfile->lineno++; - current_srcfile->colno = 1; -- } else if (text[i] == '\t') { -- current_srcfile->colno = -- ALIGN(current_srcfile->colno, TAB_SIZE); - } else { - current_srcfile->colno++; - } -@@ -246,46 +241,27 @@ srcpos_copy(struct srcpos *pos) - return pos_new; - } - -- -- --void --srcpos_dump(struct srcpos *pos) --{ -- printf("file : \"%s\"\n", -- pos->file ? (char *) pos->file : ""); -- printf("first_line : %d\n", pos->first_line); -- printf("first_column: %d\n", pos->first_column); -- printf("last_line : %d\n", pos->last_line); -- printf("last_column : %d\n", pos->last_column); -- printf("file : %s\n", pos->file->name); --} -- -- - char * - srcpos_string(struct srcpos *pos) - { - const char *fname = ""; - char *pos_str; -- int rc; - -- if (pos) -+ if (pos->file && pos->file->name) - fname = pos->file->name; - - - if (pos->first_line != pos->last_line) -- rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, -- pos->first_line, pos->first_column, -- pos->last_line, pos->last_column); -+ xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname, -+ pos->first_line, pos->first_column, -+ pos->last_line, pos->last_column); - else if (pos->first_column != pos->last_column) -- rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, -- pos->first_line, pos->first_column, -- pos->last_column); -+ xasprintf(&pos_str, "%s:%d.%d-%d", fname, -+ pos->first_line, pos->first_column, -+ pos->last_column); - else -- rc = asprintf(&pos_str, "%s:%d.%d", fname, -- pos->first_line, pos->first_column); -- -- if (rc == -1) -- die("Couldn't allocate in srcpos string"); -+ xasprintf(&pos_str, "%s:%d.%d", fname, -+ pos->first_line, pos->first_column); - - return pos_str; - } -diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h -index f81827bd6..9ded12a38 100644 ---- a/scripts/dtc/srcpos.h -+++ b/scripts/dtc/srcpos.h -@@ -17,11 +17,12 @@ - * USA - */ - --#ifndef _SRCPOS_H_ --#define _SRCPOS_H_ -+#ifndef SRCPOS_H -+#define SRCPOS_H - - #include - #include -+#include "util.h" - - struct srcfile_state { - FILE *f; -@@ -105,15 +106,12 @@ extern struct srcpos srcpos_empty; - extern void srcpos_update(struct srcpos *pos, const char *text, int len); - extern struct srcpos *srcpos_copy(struct srcpos *pos); - extern char *srcpos_string(struct srcpos *pos); --extern void srcpos_dump(struct srcpos *pos); - --extern void srcpos_verror(struct srcpos *pos, const char *prefix, -- const char *fmt, va_list va) -- __attribute__((format(printf, 3, 0))); --extern void srcpos_error(struct srcpos *pos, const char *prefix, -- const char *fmt, ...) -- __attribute__((format(printf, 3, 4))); -+extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va); -+extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...); - - extern void srcpos_set_line(char *f, int l); - --#endif /* _SRCPOS_H_ */ -+#endif /* SRCPOS_H */ -diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c -index a55d1d128..2461a3d06 100644 ---- a/scripts/dtc/treesource.c -+++ b/scripts/dtc/treesource.c -@@ -25,12 +25,12 @@ extern FILE *yyin; - extern int yyparse(void); - extern YYLTYPE yylloc; - --struct boot_info *the_boot_info; -+struct dt_info *parser_output; - bool treesource_error; - --struct boot_info *dt_from_source(const char *fname) -+struct dt_info *dt_from_source(const char *fname) - { -- the_boot_info = NULL; -+ parser_output = NULL; - treesource_error = false; - - srcfile_push(fname); -@@ -43,7 +43,7 @@ struct boot_info *dt_from_source(const char *fname) - if (treesource_error) - die("Syntax error parsing input tree\n"); - -- return the_boot_info; -+ return parser_output; - } - - static void write_prefix(FILE *f, int level) -@@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val) - static void write_propval_cells(FILE *f, struct data val) - { - void *propend = val.val + val.len; -- cell_t *cp = (cell_t *)val.val; -+ fdt32_t *cp = (fdt32_t *)val.val; - struct marker *m = val.markers; - - fprintf(f, "<"); -@@ -263,22 +263,22 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) - } - - --void dt_to_source(FILE *f, struct boot_info *bi) -+void dt_to_source(FILE *f, struct dt_info *dti) - { - struct reserve_info *re; - - fprintf(f, "/dts-v1/;\n\n"); - -- for (re = bi->reservelist; re; re = re->next) { -+ for (re = dti->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) - fprintf(f, "%s: ", l->label); - fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", -- (unsigned long long)re->re.address, -- (unsigned long long)re->re.size); -+ (unsigned long long)re->address, -+ (unsigned long long)re->size); - } - -- write_tree_source_node(f, bi->dt, 0); -+ write_tree_source_node(f, dti->dt, 0); - } - -diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh -index 075d1d7af..1a009fd19 100755 ---- a/scripts/dtc/update-dtc-source.sh -+++ b/scripts/dtc/update-dtc-source.sh -@@ -1,9 +1,10 @@ - #!/bin/sh -+# SPDX-License-Identifier: GPL-2.0 - # Simple script to update the version of DTC carried by the Linux kernel - # - # This script assumes that the dtc and the linux git trees are in the - # same directory. After building dtc in the dtc directory, it copies the --# source files and generated source files into the scripts/dtc directory -+# source files and generated source file(s) into the scripts/dtc directory - # in the kernel and creates a git commit updating them to the new - # version. - # -@@ -32,16 +33,24 @@ DTC_LINUX_PATH=`pwd`/scripts/dtc - - DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ - srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \ -- dtc-lexer.l dtc-parser.y fdtdump.c fdtput.c fdtget.c" --DTC_LIB="fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c fdt_ro.c fdt_rw.c \ -- fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h \ -- libfdt_internal.h" --DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h" -+ dtc-lexer.l dtc-parser.y" -+LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ -+ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ -+ fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" -+ -+get_last_dtc_version() { -+ git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/' -+} -+ -+last_dtc_ver=$(get_last_dtc_version) - - # Build DTC - cd $DTC_UPSTREAM_PATH - make clean - make check -+dtc_version=$(git describe HEAD) -+dtc_log=$(git log --oneline ${last_dtc_ver}..) -+ - - # Copy the files into the Linux tree - cd $DTC_LINUX_PATH -@@ -49,13 +58,22 @@ for f in $DTC_SOURCE; do - cp ${DTC_UPSTREAM_PATH}/${f} ${f} - git add ${f} - done --for f in $DTC_LIB; do -- cp ${DTC_UPSTREAM_PATH}/libfdt/${f} ${f} -- git add ${f} --done --for f in $DTC_GENERATED; do -- cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped -- git add ${f}_shipped -+for f in $LIBFDT_SOURCE; do -+ cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f} -+ git add libfdt/${f} - done - --git commit -e -v -m "scripts/dtc: Update to upstream version [CHANGEME]" -+sed -i -- 's/#include /#include "libfdt_env.h"/g' ./libfdt/libfdt.h -+sed -i -- 's/#include /#include "fdt.h"/g' ./libfdt/libfdt.h -+git add ./libfdt/libfdt.h -+ -+commit_msg=$(cat << EOF -+scripts/dtc: Update to upstream version ${dtc_version} -+ -+This adds the following commits from upstream: -+ -+${dtc_log} -+EOF -+) -+ -+git commit -e -v -s -m "${commit_msg}" -diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c -index 9d65226df..9953c32a0 100644 ---- a/scripts/dtc/util.c -+++ b/scripts/dtc/util.c -@@ -46,6 +46,36 @@ char *xstrdup(const char *s) - return d; - } - -+/* based in part from (3) vsnprintf */ -+int xasprintf(char **strp, const char *fmt, ...) -+{ -+ int n, size = 128; /* start with 128 bytes */ -+ char *p; -+ va_list ap; -+ -+ /* initial pointer is NULL making the fist realloc to be malloc */ -+ p = NULL; -+ while (1) { -+ p = xrealloc(p, size); -+ -+ /* Try to print in the allocated space. */ -+ va_start(ap, fmt); -+ n = vsnprintf(p, size, fmt, ap); -+ va_end(ap); -+ -+ /* If that worked, return the string. */ -+ if (n > -1 && n < size) -+ break; -+ /* Else try again with more space. */ -+ if (n > -1) /* glibc 2.1 */ -+ size = n + 1; /* precisely what is needed */ -+ else /* glibc 2.0 */ -+ size *= 2; /* twice the old size */ -+ } -+ *strp = p; -+ return strlen(p); -+} -+ - char *join_path(const char *path, const char *name) - { - int lenp = strlen(path); -@@ -152,7 +182,6 @@ char get_escape_char(const char *s, int *i) - int j = *i + 1; - char val; - -- assert(c); - switch (c) { - case 'a': - val = '\a'; -@@ -349,7 +378,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) - void utilfdt_print_data(const char *data, int len) - { - int i; -- const char *p = data; - const char *s; - - /* no data, don't print */ -@@ -368,7 +396,7 @@ void utilfdt_print_data(const char *data, int len) - } while (s < data + len); - - } else if ((len % 4) == 0) { -- const uint32_t *cell = (const uint32_t *)data; -+ const fdt32_t *cell = (const fdt32_t *)data; - - printf(" = <"); - for (i = 0, len /= 4; i < len; i++) -@@ -376,6 +404,7 @@ void utilfdt_print_data(const char *data, int len) - i < (len - 1) ? " " : ""); - printf(">"); - } else { -+ const unsigned char *p = (const unsigned char *)data; - printf(" = ["); - for (i = 0; i < len; i++) - printf("%02x%s", *p++, i < len - 1 ? " " : ""); -@@ -383,15 +412,16 @@ void utilfdt_print_data(const char *data, int len) - } - } - --void util_version(void) -+void NORETURN util_version(void) - { - printf("Version: %s\n", DTC_VERSION); - exit(0); - } - --void util_usage(const char *errmsg, const char *synopsis, -- const char *short_opts, struct option const long_opts[], -- const char * const opts_help[]) -+void NORETURN util_usage(const char *errmsg, const char *synopsis, -+ const char *short_opts, -+ struct option const long_opts[], -+ const char * const opts_help[]) - { - FILE *fp = errmsg ? stderr : stdout; - const char a_arg[] = ""; -diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h -index ccfdf4b12..66fba8ea7 100644 ---- a/scripts/dtc/util.h -+++ b/scripts/dtc/util.h -@@ -1,5 +1,5 @@ --#ifndef _UTIL_H --#define _UTIL_H -+#ifndef UTIL_H -+#define UTIL_H - - #include - #include -@@ -25,15 +25,27 @@ - * USA - */ - -+#ifdef __GNUC__ -+#define PRINTF(i, j) __attribute__((format (printf, i, j))) -+#define NORETURN __attribute__((noreturn)) -+#else -+#define PRINTF(i, j) -+#define NORETURN -+#endif -+ - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - --static inline void __attribute__((noreturn)) die(const char *str, ...) -+#define stringify(s) stringify_(s) -+#define stringify_(s) #s -+ -+static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) - { - va_list ap; - - va_start(ap, str); - fprintf(stderr, "FATAL ERROR: "); - vfprintf(stderr, str, ap); -+ va_end(ap); - exit(1); - } - -@@ -52,12 +64,14 @@ static inline void *xrealloc(void *p, size_t len) - void *new = realloc(p, len); - - if (!new) -- die("realloc() failed (len=%d)\n", len); -+ die("realloc() failed (len=%zd)\n", len); - - return new; - } - - extern char *xstrdup(const char *s); -+ -+extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); - extern char *join_path(const char *path, const char *name); - - /** -@@ -186,7 +200,7 @@ void utilfdt_print_data(const char *data, int len); - /** - * Show source version and exit - */ --void util_version(void) __attribute__((noreturn)); -+void NORETURN util_version(void); - - /** - * Show usage and exit -@@ -200,9 +214,10 @@ void util_version(void) __attribute__((noreturn)); - * @param long_opts The structure of long options - * @param opts_help An array of help strings (should align with long_opts) - */ --void util_usage(const char *errmsg, const char *synopsis, -- const char *short_opts, struct option const long_opts[], -- const char * const opts_help[]) __attribute__((noreturn)); -+void NORETURN util_usage(const char *errmsg, const char *synopsis, -+ const char *short_opts, -+ struct option const long_opts[], -+ const char * const opts_help[]); - - /** - * Show usage and exit -@@ -248,4 +263,4 @@ void util_usage(const char *errmsg, const char *synopsis, - case 'V': util_version(); \ - case '?': usage("unknown option"); - --#endif /* _UTIL_H */ -+#endif /* UTIL_H */ -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 607afac1c..89d4e0ad1 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1" -+#define DTC_VERSION "DTC 1.4.6" --- -2.17.0 - diff --git a/buildroot-external/patches/barebox/0002-drivers-of-implement-overlay-support.patch b/buildroot-external/patches/barebox/0002-drivers-of-implement-overlay-support.patch deleted file mode 100644 index 1db8b1f3d..000000000 --- a/buildroot-external/patches/barebox/0002-drivers-of-implement-overlay-support.patch +++ /dev/null @@ -1,1062 +0,0 @@ -From c02be471430936674acba23ad18e3a4178c2c45a Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Tue, 5 Jun 2018 22:43:53 +0000 -Subject: [PATCH 2/2] drivers: of: implement overlay support - -Origin patches are from Jan Luebbe. - -This is based on Pantelis Antoniou's overlay support for the kernel. It -has been simplified by leaving out transaction support, locking and -other details required by the Linux DT support. - -Pascal Vizeli fix some parts of resolver they was wrong ported from -linux source. - -Signed-off-by: Jan Luebbe ---- - Documentation/user/devicetree.rst | 101 ++++++++- - arch/sandbox/dts/Makefile | 5 +- - arch/sandbox/dts/sandbox-overlay.dtso | 26 +++ - arch/sandbox/dts/sandbox.dts | 6 + - commands/Kconfig | 10 + - commands/Makefile | 1 + - commands/of_overlay.c | 106 +++++++++ - drivers/of/Kconfig | 6 + - drivers/of/Makefile | 1 + - drivers/of/overlay.c | 234 +++++++++++++++++++ - drivers/of/resolver.c | 314 ++++++++++++++++++++++++++ - include/of.h | 71 ++++++ - scripts/Makefile.lib | 5 +- - 13 files changed, 882 insertions(+), 4 deletions(-) - create mode 100644 arch/sandbox/dts/sandbox-overlay.dtso - create mode 100644 commands/of_overlay.c - create mode 100644 drivers/of/overlay.c - create mode 100644 drivers/of/resolver.c - -diff --git a/Documentation/user/devicetree.rst b/Documentation/user/devicetree.rst -index 17934d86e..8b7be4f5b 100644 ---- a/Documentation/user/devicetree.rst -+++ b/Documentation/user/devicetree.rst -@@ -21,7 +21,7 @@ The internal devicetree - ----------------------- - - The devicetree consulted by barebox plays a special role. It is referred to --as the "internal devicetree." The barebox devicetree commands work on this -+as the "internal devicetree". The barebox devicetree commands work on this - devicetree. The devicetree source (DTS) files are kept in sync with the kernel DTS - files. As the FDT files are meant to be backward compatible, it should always be possible - to start a kernel with the barebox internal devicetree. However, since the barebox -@@ -83,3 +83,102 @@ you can exchange the internal devicetree during runtime using the - - oftree -f - oftree -l /new/dtb -+ -+Devicetree overlays -+------------------- -+ -+Since version 3.19, the Linux kernel supports applying "devicetree overlays" to -+its loaded device tree. This can be used to inform the kernel about additional -+non-discoverable devices after the system has booted, which is useful for modular -+boards and FPGAs. The details of the overlay format are specified in the Linux -+`kernel documentation `_ -+and an updated DTC is required to compile the overlays. -+ -+The use cases for overlays in barebox are a bit different: -+ -+* some of the modular devices are needed to boot Linux to userspace, but barebox -+ can detect which module variant is connected -+* one of several parallel or LVDS displays (which use timing data from devicetree) -+ can be connected to the SoC and should be used for boot messages -+* a generic Linux (distribution) kernel should be booted on a modular -+ system and support additional hardware on modules -+ -+barebox supports applying overlays in the internal devicetree was well using the -+:ref:`command_oftree` command with option ``-o``: -+ -+.. code-block:: none -+ -+ $ ./barebox -d arch/sandbox/dts/sandbox.dtb -i arch/sandbox/dts/sandbox-overlay.dtbo -+ add fd0 backed by file arch/sandbox/dts/sandbox-overlay.dtbo -+ -+ barebox 2015.02.0 #26 Wed Mar 4 09:41:19 CET 2015 -+ ... -+ barebox@barebox sandbox:/ of_dump -+ ... -+ dummy@0 { -+ status = "disabled"; -+ linux,phandle = <0x1>; -+ phandle = <0x1>; -+ }; -+ dummy@1 { -+ status = "disabled"; -+ linux,phandle = <0x2>; -+ phandle = <0x2>; -+ }; -+ __symbols__ { -+ dummy0 = "/dummy@0"; -+ dummy1 = "/dummy@1"; -+ }; -+ ... -+ barebox@barebox sandbox:/ of_dump -f /dev/fd0 -+ { -+ fragment@0 { -+ target = <0xdeadbeef>; -+ __overlay__ { -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ }; -+ fragment@1 { -+ target = <0xdeadbeef>; -+ __overlay__ { -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ }; -+ __fixups__ { -+ dummy0 = "/fragment@0:target:0"; -+ dummy1 = "/fragment@1:target:0"; -+ }; -+ }; -+ barebox@barebox sandbox:/ of_overlay /dev/fd0 -+ barebox@barebox sandbox:/ of_dump -+ ... -+ dummy@0 { -+ linux,phandle = <0x1>; -+ phandle = <0x1>; -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ dummy@1 { -+ linux,phandle = <0x2>; -+ phandle = <0x2>; -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ __symbols__ { -+ dummy0 = "/dummy@0"; -+ dummy1 = "/dummy@1"; -+ }; -+ ... -+ -+If you need to use a different base devicetree instead of the one compiled into -+barebox, it needs to be replaced as described in the previous section. -diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile -index 6f6838857..ede219e6f 100644 ---- a/arch/sandbox/dts/Makefile -+++ b/arch/sandbox/dts/Makefile -@@ -1,6 +1,7 @@ - ifeq ($(CONFIG_OFTREE),y) - dtb-y += \ -- sandbox.dtb -+ sandbox.dtb \ -+ sandbox-overlay.dtbo - endif - - # just to build a built-in.o. Otherwise compilation fails when no devicetree is -@@ -8,4 +9,4 @@ endif - obj- += dummy.o - - always := $(dtb-y) --clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts -+clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtbo -diff --git a/arch/sandbox/dts/sandbox-overlay.dtso b/arch/sandbox/dts/sandbox-overlay.dtso -new file mode 100644 -index 000000000..f9ced04ca ---- /dev/null -+++ b/arch/sandbox/dts/sandbox-overlay.dtso -@@ -0,0 +1,26 @@ -+/dts-v1/; -+ -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&dummy0>; -+ __overlay__ { -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&dummy1>; -+ __overlay__ { -+ status = "okay"; -+ child { -+ compatible = "barebox,dummy"; -+ }; -+ }; -+ }; -+}; -+ -diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts -index 2595aa13f..1b99a4960 100644 ---- a/arch/sandbox/dts/sandbox.dts -+++ b/arch/sandbox/dts/sandbox.dts -@@ -3,5 +3,11 @@ - #include "skeleton.dtsi" - - / { -+ dummy0: dummy@0 { -+ status = "disabled"; -+ }; - -+ dummy1: dummy@1 { -+ status = "disabled"; -+ }; - }; -diff --git a/commands/Kconfig b/commands/Kconfig -index 951a86963..22d131da3 100644 ---- a/commands/Kconfig -+++ b/commands/Kconfig -@@ -2033,6 +2033,16 @@ config CMD_OF_NODE - -c create a new node - -d delete a node - -+config CMD_OF_OVERLAY -+ tristate -+ select OFTREE -+ select OFTREE_OVERLAY -+ prompt "of_overlay" -+ help -+ Apply a dtb overlay to internal device tree -+ -+ Usage: of_overlay DTBO -+ - config CMD_OF_PROPERTY - tristate - select OFTREE -diff --git a/commands/Makefile b/commands/Makefile -index eb4796389..f404338fa 100644 ---- a/commands/Makefile -+++ b/commands/Makefile -@@ -75,6 +75,7 @@ obj-$(CONFIG_CMD_USB) += usb.o - obj-$(CONFIG_CMD_TIME) += time.o - obj-$(CONFIG_CMD_OFTREE) += oftree.o - obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o -+obj-$(CONFIG_CMD_OF_OVERLAY) += of_overlay.o - obj-$(CONFIG_CMD_OF_NODE) += of_node.o - obj-$(CONFIG_CMD_OF_DUMP) += of_dump.o - obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS) += of_display_timings.o -diff --git a/commands/of_overlay.c b/commands/of_overlay.c -new file mode 100644 -index 000000000..1b3e857bb ---- /dev/null -+++ b/commands/of_overlay.c -@@ -0,0 +1,106 @@ -+/* -+ * of_overlay.c - device tree overlay command support -+ * -+ * Copyright (C) 2015 Pengutronix, Jan Luebbe -+ * -+ * See file CREDITS for list of people who contributed to this -+ * project. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int do_of_overlay(int argc, char *argv[]) -+{ -+ struct fdt_header *fdt = NULL; -+ size_t size; -+ char *filename = NULL; -+ int ret = 0, ovinfo_cnt; -+ struct device_node *overlay = NULL, *root; -+ struct of_overlay_info *ovinfo; -+ -+ if (argc != 2) -+ return COMMAND_ERROR_USAGE; -+ -+ filename = argv[1]; -+ -+ root = of_get_root_node(); -+ if (!root) { -+ printf("no oftree loaded\n"); -+ return 1; -+ } -+ -+ fdt = read_file(filename, &size); -+ if (!fdt) { -+ printf("unable to read %s\n", filename); -+ return 1; -+ } -+ -+ overlay = of_unflatten_dtb(fdt); -+ free(fdt); -+ -+ if (IS_ERR(overlay)) { -+ printf("parse oftree: %s\n", strerror(-ret)); -+ return PTR_ERR(overlay); -+ } -+ -+ ret = of_resolve(overlay); -+ if (ret != 0) { -+ printf("resolve oftree overlay: %s\n", strerror(-ret)); -+ goto out; -+ } -+ -+ ret = of_build_overlay_info(overlay, &ovinfo_cnt, &ovinfo); -+ if (ret != 0) { -+ printf("prepare oftree overlay: %s\n", strerror(-ret)); -+ goto out; -+ } -+ -+ ret = of_overlay(ovinfo_cnt, ovinfo); -+ if (ret != 0) { -+ printf("apply oftree overlay: %s\n", strerror(-ret)); -+ goto out; -+ } -+ -+ ret = 0; -+ -+out: -+ of_delete_node(overlay); -+ return ret; -+} -+ -+BAREBOX_CMD_HELP_START(of_overlay) -+BAREBOX_CMD_HELP_TEXT("Apply a dtb overlay to internal device tree") -+BAREBOX_CMD_HELP_END -+ -+BAREBOX_CMD_START(of_overlay) -+ .cmd = do_of_overlay, -+ BAREBOX_CMD_DESC("Apply a dtb overlay") -+ BAREBOX_CMD_OPTS("DTBO") -+ BAREBOX_CMD_GROUP(CMD_GRP_MISC) -+ BAREBOX_CMD_HELP(cmd_of_overlay_help) -+BAREBOX_CMD_END -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index a1fac0e61..d90bd9c6b 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -15,6 +15,12 @@ config OFDEVICE - select DTC - bool "Enable probing of devices from the devicetree" - -+config OFTREE_OVERLAY -+ bool "Enable support for devicetree overlays" -+ depends on OFTREE -+ help -+ Allows you to modify the live tree using overlays. -+ - config OF_ADDRESS_PCI - bool - -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index ec4387006..323543461 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -6,3 +6,4 @@ obj-y += partition.o - obj-y += of_net.o - obj-$(CONFIG_MTD) += of_mtd.o - obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o -+obj-$(CONFIG_OFTREE_OVERLAY) += resolver.o overlay.o -diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -new file mode 100644 -index 000000000..a711a353f ---- /dev/null -+++ b/drivers/of/overlay.c -@@ -0,0 +1,234 @@ -+/* -+ * Functions for working with device tree overlays -+ * -+ * Copyright (C) 2012 Pantelis Antoniou -+ * Copyright (C) 2012 Texas Instruments Inc. -+ * Copyright (C) 2015 Pengutronix, Jan Luebbe -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * Apply a single overlay node recursively. -+ * -+ * All the property notifiers are appropriately called. -+ * Note that the in case of an error the target node is left -+ * in a inconsistent state. Error recovery should be performed -+ * by recording the modification using the of notifiers. -+ */ -+static int of_overlay_apply_one(struct device_node *target, -+ const struct device_node *overlay) -+{ -+ struct device_node *child, *tchild; -+ struct property *prop; -+ int ret; -+ -+ /* sanity checks */ -+ if (target == NULL || overlay == NULL) -+ return -EINVAL; -+ -+ for_each_property_of_node(overlay, prop) { -+ /* don't touch, 'name' */ -+ if (of_prop_cmp(prop->name, "name") == 0) -+ continue; -+ -+ of_delete_property(of_find_property(target, prop->name, NULL)); -+ -+ if (of_new_property(target, prop->name, prop->value, prop->length) == NULL) -+ return -ENOMEM; -+ } -+ -+ for_each_child_of_node(overlay, child) { -+ tchild = of_get_child_by_name(target, child->name); -+ if (tchild != NULL) { -+ /* apply overlay recursively */ -+ ret = of_overlay_apply_one(tchild, child); -+ -+ if (ret != 0) -+ return ret; -+ } else { -+ /* create new child */ -+ tchild = of_new_node(target, child->name); -+ if (tchild == NULL) -+ return -ENOMEM; -+ -+ /* apply the overlay */ -+ ret = of_overlay_apply_one(tchild, child); -+ if (ret != 0) { -+ of_delete_node(tchild); -+ return ret; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * of_overlay - Apply @count overlays pointed at by @ovinfo_tab -+ * @count: Number of of_overlay_info's -+ * @ovinfo_tab: Array of overlay_info's to apply -+ * -+ * Applies the overlays given, while handling all error conditions -+ * appropriately. Either the operation succeeds, or if it fails the -+ * live tree is reverted to the state before the attempt. -+ * Returns 0, or an error if the overlay attempt failed. -+ */ -+int of_overlay(int count, struct of_overlay_info *ovinfo_tab) -+{ -+ struct of_overlay_info *ovinfo; -+ int i, err; -+ -+ if (!ovinfo_tab) -+ return -EINVAL; -+ -+ for (i = 0; i < count; i++) { -+ ovinfo = &ovinfo_tab[i]; -+ err = of_overlay_apply_one(ovinfo->target, ovinfo->overlay); -+ if (err != 0) { -+ pr_err("%s: overlay failed '%s'\n", -+ __func__, ovinfo->target->full_name); -+ goto err_fail; -+ } -+ } -+ -+ return 0; -+ -+err_fail: -+ return err; -+} -+ -+/** -+ * of_fill_overlay_info - Fill an overlay info structure -+ * @info_node: Device node containing the overlay -+ * @ovinfo: Pointer to the overlay info structure to fill -+ * -+ * Fills an overlay info structure with the overlay information -+ * from a device node. This device node must have a target property -+ * which contains a phandle of the overlay target node, and an -+ * __overlay__ child node which has the overlay contents. -+ * Both ovinfo->target & ovinfo->overlay have their references taken. -+ * -+ * Returns 0 on success, or a negative error value. -+ */ -+int of_fill_overlay_info(struct device_node *info_node, -+ struct of_overlay_info *ovinfo) -+{ -+ const char *target_path; -+ u32 target_handle; -+ int ret; -+ -+ if (!info_node || !ovinfo) -+ return -EINVAL; -+ -+ ret = of_property_read_u32(info_node, "target", &target_handle); -+ if (ret == 0) { -+ ovinfo->target = of_find_node_by_phandle(target_handle); -+ } else { -+ ret = of_property_read_string(info_node, "target-path", &target_path); -+ if (ret == 0) { -+ ovinfo->target = of_find_node_by_path(target_path); -+ } -+ } -+ if (ovinfo->target == NULL) -+ goto err_fail; -+ -+ ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__"); -+ if (ovinfo->overlay == NULL) -+ goto err_fail; -+ -+ return 0; -+ -+err_fail: -+ memset(ovinfo, 0, sizeof(*ovinfo)); -+ return -EINVAL; -+} -+ -+/** -+ * of_build_overlay_info - Build an overlay info array -+ * @tree: Device node containing all the overlays -+ * @cntp: Pointer to where the overlay info count will be help -+ * @ovinfop: Pointer to the pointer of an overlay info structure. -+ * -+ * Helper function that given a tree containing overlay information, -+ * allocates and builds an overlay info array containing it, ready -+ * for use using of_overlay. -+ * -+ * Returns 0 on success with the @cntp @ovinfop pointers valid, -+ * while on error a negative error value is returned. -+ */ -+int of_build_overlay_info(struct device_node *tree, -+ int *cntp, struct of_overlay_info **ovinfop) -+{ -+ struct device_node *node; -+ struct of_overlay_info *ovinfo; -+ int cnt, err; -+ -+ if (tree == NULL || cntp == NULL || ovinfop == NULL) -+ return -EINVAL; -+ -+ /* worst case; every child is a node */ -+ cnt = 0; -+ for_each_child_of_node(tree, node) -+ cnt++; -+ -+ ovinfo = kzalloc(cnt * sizeof(*ovinfo), GFP_KERNEL); -+ if (ovinfo == NULL) -+ return -ENOMEM; -+ -+ cnt = 0; -+ for_each_child_of_node(tree, node) { -+ memset(&ovinfo[cnt], 0, sizeof(*ovinfo)); -+ err = of_fill_overlay_info(node, &ovinfo[cnt]); -+ if (err == 0) -+ cnt++; -+ } -+ -+ /* if nothing filled, return error */ -+ if (cnt == 0) { -+ kfree(ovinfo); -+ return -ENODEV; -+ } -+ -+ *cntp = cnt; -+ *ovinfop = ovinfo; -+ -+ return 0; -+} -+ -+/** -+ * of_free_overlay_info - Free an overlay info array -+ * @count: Number of of_overlay_info's -+ * @ovinfo_tab: Array of overlay_info's to free -+ * -+ * Releases the memory of a previously allocate ovinfo array -+ * by of_build_overlay_info. -+ * Returns 0, or an error if the arguments are bogus. -+ */ -+int of_free_overlay_info(int count, struct of_overlay_info *ovinfo_tab) -+{ -+ struct of_overlay_info *ovinfo; -+ int i; -+ -+ if (!ovinfo_tab || count < 0) -+ return -EINVAL; -+ -+ /* do it in reverse */ -+ for (i = count - 1; i >= 0; i--) -+ ovinfo = &ovinfo_tab[i]; -+ -+ kfree(ovinfo_tab); -+ -+ return 0; -+} -diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c -new file mode 100644 -index 000000000..7d159265b ---- /dev/null -+++ b/drivers/of/resolver.c -@@ -0,0 +1,314 @@ -+/* -+ * Functions for dealing with DT resolution -+ * -+ * Copyright (C) 2012 Pantelis Antoniou -+ * Copyright (C) 2012 Texas Instruments Inc. -+ * Copyright (C) 2015 Pengutronix, Jan Luebbe -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * Adjust a subtree's phandle values by a given delta. -+ * Makes sure not to just adjust the device node's phandle value, -+ * but modify the phandle properties values as well. -+ */ -+static void of_adjust_tree_phandles(struct device_node *node, -+ int phandle_delta) -+{ -+ struct device_node *child; -+ struct property *prop; -+ phandle phandle; -+ -+ /* first adjust the node's phandle direct value */ -+ if (node->phandle != 0 && node->phandle != OF_PHANDLE_ILLEGAL) -+ node->phandle += phandle_delta; -+ -+ /* now adjust phandle & linux,phandle values */ -+ for_each_property_of_node(node, prop) { -+ /* only look for these two */ -+ if (of_prop_cmp(prop->name, "phandle") != 0 && -+ of_prop_cmp(prop->name, "linux,phandle") != 0) -+ continue; -+ -+ /* must be big enough */ -+ if (prop->length < 4) -+ continue; -+ -+ /* read phandle value */ -+ phandle = be32_to_cpu(*(uint32_t *)prop->value); -+ if (phandle == OF_PHANDLE_ILLEGAL) /* unresolved */ -+ continue; -+ -+ /* adjust */ -+ *(uint32_t *)prop->value = cpu_to_be32(node->phandle); -+ } -+ -+ /* now do the children recursively */ -+ for_each_child_of_node(node, child) -+ of_adjust_tree_phandles(child, phandle_delta); -+} -+ -+/** -+ * Adjust the local phandle references by the given phandle delta. -+ * Assumes the existances of a __local_fixups__ node at the root -+ * of the tree. Does not take any devtree locks so make sure you -+ * call this on a tree which is at the detached state. -+ */ -+static int of_adjust_tree_phandle_references(struct device_node *local_fixups, -+ struct device_node *overlay, int phandle_delta) -+{ -+ phandle phandle; -+ struct device_node *child, *overlay_child = NULL; -+ struct property *fixprop, *prop = NULL; -+ int i, count, err; -+ unsigned int off; -+ -+ if (!local_fixups) -+ return 0; -+ -+ for_each_property_of_node(local_fixups, fixprop) { -+ /* skip properties added automatically */ -+ if (!of_prop_cmp(fixprop->name, "name") || -+ !of_prop_cmp(fixprop->name, "phandle") || -+ !of_prop_cmp(fixprop->name, "linux,phandle")) -+ continue; -+ -+ if ((fixprop->length % 4) != 0 || fixprop->length == 0) -+ return -EINVAL; -+ count = fixprop->length / sizeof(uint32_t); -+ -+ for_each_property_of_node(overlay, prop) { -+ if (!of_prop_cmp(fixprop->name, prop->name)) -+ break; -+ } -+ -+ if (!prop) -+ return -EINVAL; -+ -+ for (i=0; i < count; i++) { -+ off = be32_to_cpu(((uint32_t *)fixprop->value)[i]); -+ if ((off + 4) > prop->length) -+ return -EINVAL; -+ -+ phandle = be32_to_cpu(*(uint32_t *)(prop->value + off)); -+ phandle += phandle_delta; -+ *(uint32_t *)(prop->value + off) = cpu_to_be32(phandle); -+ } -+ } -+ -+ /* -+ * These nested loops recurse down two subtrees in parallel, where the -+ * node names in the two subtrees match. -+ * -+ * The roots of the subtrees are the overlay's __local_fixups__ node -+ * and the overlay's root node. -+ */ -+ for_each_child_of_node(local_fixups, child) { -+ -+ for_each_child_of_node(overlay, overlay_child) -+ if (!of_node_cmp(child->name, overlay_child->name)) -+ break; -+ -+ if (!overlay_child) -+ return -EINVAL; -+ -+ err = of_adjust_tree_phandle_references(child, overlay_child, -+ phandle_delta); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+/** -+ * of_resolve - Resolve the given node against the live tree. -+ * -+ * @resolve: Node to resolve -+ * -+ * Perform dynamic Device Tree resolution against the live tree -+ * to the given node to resolve. This depends on the live tree -+ * having a __symbols__ node, and the resolve node the __fixups__ & -+ * __local_fixups__ nodes (if needed). -+ * The result of the operation is a resolve node that it's contents -+ * are fit to be inserted or operate upon the live tree. -+ * Returns 0 on success or a negative error value on error. -+ */ -+int of_resolve(struct device_node *resolve) -+{ -+ struct device_node *child, *refnode, *local_fixups = NULL; -+ struct device_node *root_sym, *resolve_sym, *resolve_fix; -+ struct property *rprop, *sprop; -+ const char *refpath; -+ char *propval, *propcur, *propend, *nodestr, *propstr, *s; -+ int offset, propcurlen; -+ phandle phandle, phandle_delta; -+ int err; -+ bool found = false; -+ -+ /* the resolve node must exist */ -+ if (resolve == NULL) { -+ return -EINVAL; -+ } -+ -+ /* first we need to adjust the phandles */ -+ phandle_delta = of_get_tree_max_phandle(NULL) + 1; -+ of_adjust_tree_phandles(resolve, phandle_delta); -+ -+ /* second we need lookup local fixups of phandles */ -+ local_fixups = of_find_node_by_name(resolve, "__local_fixups__"); -+ err = of_adjust_tree_phandle_references(local_fixups, resolve, -+ phandle_delta); -+ -+ if (err != 0) -+ return err; -+ -+ root_sym = NULL; -+ resolve_sym = NULL; -+ resolve_fix = NULL; -+ -+ /* this may fail (if no fixups are required) */ -+ root_sym = of_find_node_by_path("/__symbols__"); -+ -+ /* locate the symbols & fixups nodes on resolve */ -+ for_each_child_of_node(resolve, child) { -+ if (resolve_sym == NULL && -+ of_node_cmp(child->name, "__symbols__") == 0) -+ resolve_sym = child; -+ -+ if (resolve_fix == NULL && -+ of_node_cmp(child->name, "__fixups__") == 0) -+ resolve_fix = child; -+ -+ /* both found, don't bother anymore */ -+ if (resolve_sym != NULL && resolve_fix != NULL) -+ break; -+ } -+ -+ /* we do allow for the case where no fixups are needed */ -+ if (resolve_fix == NULL) -+ goto merge_sym; -+ -+ /* we need to fixup, but no root symbols... */ -+ if (root_sym == NULL) -+ return -EINVAL; -+ -+ for_each_property_of_node(resolve_fix, rprop) { -+ /* skip properties added automatically */ -+ if (of_prop_cmp(rprop->name, "name") == 0) -+ continue; -+ -+ err = of_property_read_string(root_sym, -+ rprop->name, &refpath); -+ if (err != 0) { -+ pr_err("%s: Could not find symbol '%s'\n", -+ __func__, rprop->name); -+ goto err_fail; -+ } -+ -+ refnode = of_find_node_by_path(refpath); -+ if (refnode == NULL) { -+ pr_err("%s: Could not find node by path '%s'\n", -+ __func__, refpath); -+ err = -ENOENT; -+ goto err_fail; -+ } -+ -+ phandle = refnode->phandle; -+ -+ pr_debug("%s: %s phandle is 0x%08x\n", -+ __func__, rprop->name, phandle); -+ -+ /* make a copy */ -+ propval = kmalloc(rprop->length, GFP_KERNEL); -+ if (propval == NULL) { -+ pr_err("%s: Could not copy value of '%s'\n", -+ __func__, rprop->name); -+ err = -ENOMEM; -+ goto err_fail; -+ } -+ -+ memcpy(propval, rprop->value, rprop->length); -+ -+ propend = propval + rprop->length; -+ for (propcur = propval; propcur < propend; -+ propcur += propcurlen + 1) { -+ propcurlen = strlen(propcur); -+ -+ nodestr = propcur; -+ s = strchr(propcur, ':'); -+ if (s == NULL) { -+ pr_err("%s: Illegal symbol " -+ "entry '%s' (1)\n", -+ __func__, (char *)rprop->value); -+ kfree(propval); -+ err = -EINVAL; -+ goto err_fail; -+ } -+ *s++ = '\0'; -+ -+ propstr = s; -+ s = strchr(s, ':'); -+ if (s == NULL) { -+ pr_err("%s: Illegal symbol " -+ "entry '%s' (2)\n", -+ __func__, (char *)rprop->value); -+ kfree(propval); -+ err = -EINVAL; -+ goto err_fail; -+ } -+ -+ *s++ = '\0'; -+ offset = simple_strtoul(s, NULL, 10); -+ -+ /* look into the resolve node for the full path */ -+ refnode = of_find_node_by_path_from(resolve, nodestr); -+ if (refnode == NULL) { -+ pr_err("%s: Could not find refnode '%s'\n", -+ __func__, (char *)rprop->value); -+ kfree(propval); -+ err = -ENOENT; -+ goto err_fail; -+ } -+ -+ /* now find the property */ -+ found = false; -+ for_each_property_of_node(refnode, sprop) -+ if (of_prop_cmp(sprop->name, propstr) == 0) { -+ found = true; -+ break; -+ } -+ -+ if (!found) { -+ pr_err("%s: Could not find property '%s'\n", -+ __func__, (char *)rprop->value); -+ kfree(propval); -+ err = -ENOENT; -+ goto err_fail; -+ } -+ -+ *(uint32_t *)(sprop->value + offset) = -+ cpu_to_be32(phandle); -+ } -+ -+ kfree(propval); -+ } -+ -+merge_sym: -+ return 0; -+ -+err_fail: -+ return err; -+} -diff --git a/include/of.h b/include/of.h -index fec51bb94..91476ae47 100644 ---- a/include/of.h -+++ b/include/of.h -@@ -730,6 +730,8 @@ static inline struct device_node *of_find_matching_node( - #define for_each_available_child_of_node(parent, child) \ - for (child = of_get_next_available_child(parent, NULL); child != NULL; \ - child = of_get_next_available_child(parent, child)) -+#define for_each_property_of_node(dn, pp) \ -+ list_for_each_entry(pp, &dn->properties, list) - - /** - * of_property_read_bool - Findfrom a property -@@ -850,4 +852,73 @@ static inline struct device_node *of_find_root_node(struct device_node *node) - - return node; - } -+ -+/* illegal phandle value (set when unresolved) */ -+#define OF_PHANDLE_ILLEGAL 0xdeadbeef -+ -+#ifdef CONFIG_OFTREE_OVERLAY -+ -+extern int of_resolve(struct device_node *resolve); -+ -+#else -+ -+static inline int of_resolve(struct device_node *resolve) -+{ -+ return -ENOSYS; -+} -+ -+#endif -+ -+/** -+ * Overlay support -+ */ -+ -+/** -+ * struct of_overlay_info - Holds a single overlay info -+ * @target: target of the overlay operation -+ * @overlay: pointer to the overlay contents node -+ * -+ * Holds a single overlay state. -+ */ -+struct of_overlay_info { -+ struct device_node *target; -+ struct device_node *overlay; -+}; -+ -+#ifdef CONFIG_OFTREE_OVERLAY -+ -+extern int of_overlay(int count, struct of_overlay_info *ovinfo_tab); -+ -+extern int of_fill_overlay_info(struct device_node *info_node, -+ struct of_overlay_info *ovinfo); -+extern int of_build_overlay_info(struct device_node *tree, -+ int *cntp, struct of_overlay_info **ovinfop); -+extern int of_free_overlay_info(int cnt, struct of_overlay_info *ovinfo); -+ -+#else -+ -+static inline int of_overlay(int count, struct of_overlay_info *ovinfo_tab) -+{ -+ return -ENOSYS; -+} -+ -+static inline int of_fill_overlay_info(struct device_node *info_node, -+ struct of_overlay_info *ovinfo) -+{ -+ return -ENOSYS; -+} -+ -+static inline int of_build_overlay_info(struct device_node *tree, -+ int *cntp, struct of_overlay_info **ovinfop) -+{ -+ return -ENOSYS; -+} -+ -+static inline int of_free_overlay_info(int cnt, struct of_overlay_info *ovinfo) -+{ -+ return -ENOSYS; -+} -+ -+#endif -+ - #endif /* __OF_H */ -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 272b5981e..e7cea55c4 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -261,7 +261,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb $(srctree)/scripts/gen-dtb-s FORCE - - quiet_cmd_dtc = DTC $@ - cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -- $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \ -+ $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ - -i $(srctree)/arch/$(SRCARCH)/dts $(DTC_FLAGS) \ - -i $(srctree)/dts/src/$(SRCARCH) \ - -d $(depfile).dtc $(dtc-tmp) ; \ -@@ -270,6 +270,9 @@ cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ - $(obj)/%.dtb: $(src)/%.dts FORCE - $(call if_changed_dep,dtc) - -+$(obj)/%.dtbo: $(src)/%.dtso FORCE -+ $(call if_changed_dep,dtc) -+ - dtc-tmp = $(subst $(comma),_,$(dot-target).dts) - - obj-y += $(patsubst %,%.bbenv$(DEFAULT_COMPRESSION_SUFFIX).o,$(bbenv-y)) --- -2.17.0 - diff --git a/buildroot-external/patches/barebox/0003-drivers-of-bugfix-partition-fixups.patch b/buildroot-external/patches/barebox/0003-drivers-of-bugfix-partition-fixups.patch deleted file mode 100644 index 82937ab1e..000000000 --- a/buildroot-external/patches/barebox/0003-drivers-of-bugfix-partition-fixups.patch +++ /dev/null @@ -1,34 +0,0 @@ -From cf05dfaa34d8502041aa2354f3b8c97ca4d250c9 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Thu, 7 Jun 2018 17:36:00 +0000 -Subject: [PATCH 1/1] drivers: of: bugfix partition fixups - -If we load a new device tree for linux kernel with a diferent layout, -the fixup of partition going into endless loop. Exactly the of_find_property -function will never come back on a invalid device_node. - -My patch check, if the device will exists on device tree before we run the -fixup. - -Signed-off-by: Pascal Vizeli ---- - drivers/of/partition.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/of/partition.c b/drivers/of/partition.c -index aa6e601b7..17e420964 100644 ---- a/drivers/of/partition.c -+++ b/drivers/of/partition.c -@@ -140,6 +140,9 @@ static int of_partition_fixup(struct device_node *root, void *ctx) - if (!cdev->device_node) - return -EINVAL; - -+ if (!of_find_node_by_path(cdev->device_node->full_name)) -+ return -EINVAL; -+ - list_for_each_entry(partcdev, &cdev->partitions, partition_entry) { - if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE) - continue; --- -2.17.1 - diff --git a/buildroot-external/patches/barebox/0004-command-add-fix_bootargs.patch b/buildroot-external/patches/barebox/0004-command-add-fix_bootargs.patch deleted file mode 100644 index 07769462d..000000000 --- a/buildroot-external/patches/barebox/0004-command-add-fix_bootargs.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 5facf78a36c30c47849c338bf685f69849173f87 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Fri, 8 Jun 2018 20:45:32 +0000 -Subject: [PATCH 1/1] command: add fix_bootargs - -Signed-off-by: Pascal Vizeli ---- - commands/Kconfig | 13 +++++ - commands/Makefile | 1 + - commands/fix_bootargs.c | 105 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 119 insertions(+) - create mode 100644 commands/fix_bootargs.c - -diff --git a/commands/Kconfig b/commands/Kconfig -index 951a86963..4cc55a358 100644 ---- a/commands/Kconfig -+++ b/commands/Kconfig -@@ -2137,6 +2137,19 @@ config CMD_SEED - help - Seed the pseudo random number generator (PRNG) - -+config CMD_FIX_BOOTARGS -+ tristate -+ select GLOBALVAR -+ select OFTREE -+ prompt "fix_bootargs" -+ help -+ Read bootargs from device tree and set to 'linux.bootargs.chosen' -+ -+ Usage: fix_bootargs [-f DTB] -+ -+ Options: -+ -f DTB Read it from a dtb file. -+ - # end Miscellaneous commands - endmenu - -diff --git a/commands/Makefile b/commands/Makefile -index eb4796389..fafa8b145 100644 ---- a/commands/Makefile -+++ b/commands/Makefile -@@ -122,4 +122,5 @@ obj-$(CONFIG_CMD_SPD_DECODE) += spd_decode.o - obj-$(CONFIG_CMD_MMC_EXTCSD) += mmc_extcsd.o - obj-$(CONFIG_CMD_NAND_BITFLIP) += nand-bitflip.o - obj-$(CONFIG_CMD_SEED) += seed.o -+obj-$(CONFIG_CMD_FIX_BOOTARGS) += fix_bootargs.o - obj-$(CONFIG_CMD_IP_ROUTE_GET) += ip-route-get.o -diff --git a/commands/fix_bootargs.c b/commands/fix_bootargs.c -new file mode 100644 -index 000000000..f58a4ab1d ---- /dev/null -+++ b/commands/fix_bootargs.c -@@ -0,0 +1,105 @@ -+/* -+ * of_dump.c - dump devicetrees to the console -+ * -+ * Copyright (c) 2018 Pascal Vizeli , Hass.io -+ * -+ * See file CREDITS for list of people who contributed to this -+ * project. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int do_fix_bootargs(int argc, char *argv[]) -+{ -+ int opt; -+ int ret = 0; -+ struct device_node *root = NULL, *node = NULL, *of_free = NULL; -+ struct property *prop = NULL; -+ char *dtbfile = NULL; -+ size_t size; -+ -+ while ((opt = getopt(argc, argv, "f")) > 0) { -+ switch (opt) { -+ case 'f': -+ dtbfile = optarg; -+ break; -+ default: -+ return COMMAND_ERROR_USAGE; -+ } -+ } -+ -+ if (dtbfile) { -+ void *fdt; -+ -+ fdt = read_file(dtbfile, &size); -+ if (!fdt) { -+ printf("unable to read %s: %s\n", dtbfile, strerror(errno)); -+ return -errno; -+ } -+ -+ root = of_unflatten_dtb(fdt); -+ -+ free(fdt); -+ -+ if (IS_ERR(root)) { -+ ret = PTR_ERR(root); -+ goto end; -+ } -+ -+ of_free = root; -+ } else { -+ root = of_get_root_node(); -+ } -+ -+ node = of_find_node_by_path_or_alias(root, "/chosen"); -+ if (!node) { -+ printf("Cannot find chosen\n"); -+ ret = -ENOENT; -+ goto end; -+ } -+ -+ prop = of_find_property(node, "bootargs", NULL); -+ if (!prop) { -+ printf("Cannot find bootargs\n"); -+ ret = -ENOENT; -+ goto end; -+ } -+ -+ ret = globalvar_add_simple("linux.bootargs.chosen", prop->value); -+ -+end: -+ if (of_free) -+ of_delete_node(of_free); -+ return ret; -+} -+ -+BAREBOX_CMD_HELP_START(fix_bootargs) -+BAREBOX_CMD_HELP_TEXT("Options:") -+BAREBOX_CMD_HELP_OPT ("-f dtb", "work on dtb instead of internal devicetree\n") -+BAREBOX_CMD_HELP_END -+ -+BAREBOX_CMD_START(fix_bootargs) -+ .cmd = do_fix_bootargs, -+ BAREBOX_CMD_DESC("dump devicetree nodes") -+ BAREBOX_CMD_OPTS("[-f DTB]") -+ BAREBOX_CMD_HELP(cmd_fix_bootargs_help) -+BAREBOX_CMD_END --- -2.17.1 - diff --git a/buildroot-external/rootfs-overlay/etc/fw_env.config b/buildroot-external/rootfs-overlay/etc/fw_env.config new file mode 100644 index 000000000..cb8888e9f --- /dev/null +++ b/buildroot-external/rootfs-overlay/etc/fw_env.config @@ -0,0 +1 @@ +/mnt/state/hassos.env 0x0000 0x4000 diff --git a/buildroot-external/rootfs-overlay/etc/rauc/system.conf b/buildroot-external/rootfs-overlay/etc/rauc/system.conf index 289d45058..42cf2b340 100644 --- a/buildroot-external/rootfs-overlay/etc/rauc/system.conf +++ b/buildroot-external/rootfs-overlay/etc/rauc/system.conf @@ -2,7 +2,7 @@ compatible=%COMPATIBLE% mountprefix=/run/rauc statusfile=/mnt/data/rauc.db -bootloader=barebox +bootloader=%BOOTLOADER% [keyring] path=/etc/rauc/keyring.pem @@ -10,14 +10,24 @@ path=/etc/rauc/keyring.pem [slot.boot.0] device=/dev/disk/by-partuuid/b3dd0952-733c-4c88-8cba-cab9b8b4377f type=vfs -bootname=boot + +[slot.kernel.0] +device=/dev/disk/by-partuuid/26700fc6-b0bc-4ccf-9837-ea1a4cba3e65 +type=ext4 +bootname=A + +[slot.kernel.1] +device=/dev/disk/by-partuuid/fc02a4f0-5350-406f-93a2-56cbed636b5f +type=ext4 +bootname=B [slot.rootfs.0] device=/dev/disk/by-partuuid/8d3d53e3-6d49-4c38-8349-aff6859e82fd type=raw -bootname=system0 +parent=kernel.0 [slot.rootfs.1] device=/dev/disk/by-partuuid/a3ec664e-32ce-4665-95ea-7ae90ce9aa20 type=raw -bootname=system1 +parent=kernel.1 + diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/mnt-state.mount b/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/mnt-state.mount new file mode 120000 index 000000000..b6842350e --- /dev/null +++ b/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/mnt-state.mount @@ -0,0 +1 @@ +/usr/lib/systemd/system/mnt-state.mount \ No newline at end of file diff --git a/buildroot-external/rootfs-overlay/mnt/state/.empty b/buildroot-external/rootfs-overlay/mnt/state/.empty new file mode 100644 index 000000000..e69de29bb diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-boot.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-boot.mount index 5658e82d4..e535f1ca2 100644 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-boot.mount +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-boot.mount @@ -11,4 +11,4 @@ Where=/mnt/boot Type=auto [Install] -WantedBy=multi-user.target +WantedBy=local-fs.target diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-data.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-data.mount index 53cbd320d..e1633958d 100644 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-data.mount +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-data.mount @@ -12,4 +12,4 @@ Where=/mnt/data Type=ext4 [Install] -WantedBy=multi-user.target +WantedBy=local-fs.target diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-overlay.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-overlay.mount index 5fa9b62ec..e982a430d 100644 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-overlay.mount +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-overlay.mount @@ -10,4 +10,4 @@ Where=/mnt/overlay Type=ext4 [Install] -WantedBy=multi-user.target +WantedBy=local-fs.target diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount new file mode 100644 index 000000000..10cb32d3e --- /dev/null +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount @@ -0,0 +1,14 @@ +[Unit] +Description=HassOS bootstate partition +DefaultDependencies=no +Before=umount.target +After=local-fs.target rauc.service +Conflicts=umount.target + +[Mount] +What=LABEL=hassos-bootstate +Where=/mnt/state +Type=ext2 + +[Install] +WantedBy=local-fs.target diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/rauc-good.timer b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/rauc-good.timer index 2d4016870..fa79b78fd 100644 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/rauc-good.timer +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/rauc-good.timer @@ -2,7 +2,7 @@ Description=HassOS mark boot partition as good [Timer] -OnBootSec=30sec +OnBootSec=1min [Install] WantedBy=timers.target diff --git a/buildroot-external/rootfs-overlay/usr/sbin/hassos-expand b/buildroot-external/rootfs-overlay/usr/sbin/hassos-expand index eec4ebccf..8ace0e930 100755 --- a/buildroot-external/rootfs-overlay/usr/sbin/hassos-expand +++ b/buildroot-external/rootfs-overlay/usr/sbin/hassos-expand @@ -12,7 +12,7 @@ fi # Resize & Reload partition echo "[INFO] Update hassos-data partition" -sgdisk -d 6 -n 6:0:0 -c 6:"hassos-data" -t 6:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 6:"a52a4597-fa3a-4851-aefd-2fbe9f849079" ${DEVICE_ROOT} +sgdisk -d 8 -n 8:0:0 -c 8:"hassos-data" -t 8:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 8:"a52a4597-fa3a-4851-aefd-2fbe9f849079" ${DEVICE_ROOT} sgdisk -v ${DEVICE_ROOT} partx -u ${DEVICE_ROOT} diff --git a/buildroot-external/scripts/hdd-image.sh b/buildroot-external/scripts/hdd-image.sh index 4201029e1..ad2a2eb20 100755 --- a/buildroot-external/scripts/hdd-image.sh +++ b/buildroot-external/scripts/hdd-image.sh @@ -4,13 +4,16 @@ BOOT_UUID="b3dd0952-733c-4c88-8cba-cab9b8b4377f" BOOTSTATE_UUID="33236519-7F32-4DFF-8002-3390B62C309D" SYSTEM0_UUID="8d3d53e3-6d49-4c38-8349-aff6859e82fd" SYSTEM1_UUID="a3ec664e-32ce-4665-95ea-7ae90ce9aa20" +KERNEL0_UUID="26700fc6-b0bc-4ccf-9837-ea1a4cba3e65" +KERNEL1_UUID="fc02a4f0-5350-406f-93a2-56cbed636b5f" OVERLAY_UUID="f1326040-5236-40eb-b683-aaa100a9afcf" DATA_UUID="a52a4597-fa3a-4851-aefd-2fbe9f849079" BOOT_SIZE=32M BOOTSTATE_SIZE=8M SYSTEM_SIZE=256M -OVERLAY_SIZE=64M +KERNEL_SIZE=16M +OVERLAY_SIZE=96M DATA_SIZE=1G @@ -33,17 +36,58 @@ function create_overlay_image() { } +function create_kernel_image() { + local kernel0_img="${1}/kernel0.ext4" + local kernel1_img="${1}/kernel1.ext4" + local kernel=${1}/${2} + + # Make image + dd if=/dev/zero of=${kernel0_img} bs=${KERNEL_SIZE} count=1 + mkfs.ext4 -L "hassos-kernel0" -E lazy_itable_init=0,lazy_journal_init=0 ${kernel0_img} + dd if=/dev/zero of=${kernel1_img} bs=${KERNEL_SIZE} count=1 + mkfs.ext4 -L "hassos-kernel1" -E lazy_itable_init=0,lazy_journal_init=0 ${kernel1_img} + + # Mount / init file structs + mkdir -p /mnt/data/ + mount -o loop ${kernel0_img} /mnt/data + cp -f ${kernel} /mnt/data/ + umount /mnt/data +} + + +function create_barebox_state_image() { + local bootstate_img="${1}/bootstate.img" + + dd if=/dev/zero of=${bootstate_img} bs=${BOOTSTATE_SIZE} count=1 +} + + +function create_uboot_state_image() { + local bootstate_img="${1}/bootstate.img" + + dd if=/dev/zero of=${bootstate_img} bs=${BOOTSTATE_SIZE} count=1 + #mkfs.ext4 -L "hassos-bootstate" -E lazy_itable_init=0 -O ^has_journal ${bootstate_img} + mkfs.ext2 -L "hassos-bootstate" -E lazy_itable_init=0 ${bootstate_img} +} + + function create_disk_image() { local boot_img="${1}/boot.vfat" local rootfs_img="${1}/rootfs.squashfs" local overlay_img="${1}/overlay.ext4" local data_img="${1}/data.ext4" + local kernel0_img="${1}/kernel0.ext4" + local kernel1_img="${1}/kernel1.ext4" + local bootstate_img="${1}/bootstate.img" local hdd_img=${2} local hdd_count=${3:-2} local loop_dev="/dev/mapper/$(losetup -f | cut -d'/' -f3)" local boot_offset=0 + local bootstate_offset=0 local rootfs_offset=0 + local kernel0_offset=0 + local kernel1_offset=0 local overlay_offset=0 local data_offset=0 @@ -54,18 +98,33 @@ function create_disk_image() { # Partition layout boot_offset="$(sgdisk -F ${hdd_img})" sgdisk -n 1:0:+${BOOT_SIZE} -c 1:"hassos-boot" -t 1:"C12A7328-F81F-11D2-BA4B-00A0C93EC93B" -u 1:${BOOT_UUID} ${hdd_img} + + kernel0_offset="$(sgdisk -F ${hdd_img})" + sgdisk -n 2:0:+${KERNEL_SIZE} -c 2:"hassos-kernel0" -t 2:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 2:${KERNEL0_UUID} ${hdd_img} + rootfs_offset="$(sgdisk -F ${hdd_img})" - sgdisk -n 2:0:+${SYSTEM_SIZE} -c 2:"hassos-system0" -t 2:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 2:${SYSTEM0_UUID} ${hdd_img} - sgdisk -n 3:0:+${SYSTEM_SIZE} -c 3:"hassos-system1" -t 3:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 3:${SYSTEM1_UUID} ${hdd_img} - sgdisk -n 4:0:+${BOOTSTATE_SIZE} -c 4:"hassos-bootstate" -u 4:${BOOTSTATE_UUID} ${hdd_img} + sgdisk -n 3:0:+${SYSTEM_SIZE} -c 3:"hassos-system0" -t 3:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 3:${SYSTEM0_UUID} ${hdd_img} + + kernel1_offset="$(sgdisk -F ${hdd_img})" + sgdisk -n 4:0:+${KERNEL_SIZE} -c 4:"hassos-kernel1" -t 4:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 4:${KERNEL1_UUID} ${hdd_img} + + sgdisk -n 5:0:+${SYSTEM_SIZE} -c 5:"hassos-system1" -t 5:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 5:${SYSTEM1_UUID} ${hdd_img} + + bootstate_offset="$(sgdisk -F ${hdd_img})" + sgdisk -n 6:0:+${BOOTSTATE_SIZE} -c 6:"hassos-bootstate" -u 6:${BOOTSTATE_UUID} ${hdd_img} + overlay_offset="$(sgdisk -F ${hdd_img})" - sgdisk -n 5:0:+${OVERLAY_SIZE} -c 5:"hassos-overlay" -t 5:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 5:${OVERLAY_UUID} ${hdd_img} + sgdisk -n 7:0:+${OVERLAY_SIZE} -c 7:"hassos-overlay" -t 7:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 7:${OVERLAY_UUID} ${hdd_img} + data_offset="$(sgdisk -F ${hdd_img})" - sgdisk -n 6:0:+${DATA_SIZE} -c 6:"hassos-data" -t 6:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 6:${DATA_UUID} ${hdd_img} - sgdisk -v + sgdisk -n 8:0:+${DATA_SIZE} -c 8:"hassos-data" -t 8:"0FC63DAF-8483-4772-8E79-3D69D8477DE4" -u 8:${DATA_UUID} ${hdd_img} # Write Images + sgdisk -v dd if=${boot_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${boot_offset} + dd if=${bootstate_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${bootstate_offset} + dd if=${kernel0_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${kernel0_offset} + dd if=${kernel1_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${kernel1_offset} dd if=${rootfs_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${rootfs_offset} dd if=${overlay_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${overlay_offset} dd if=${data_img} of=${hdd_img} conv=notrunc bs=512 obs=512 seek=${data_offset} @@ -76,5 +135,5 @@ function fix_disk_image_mbr() { local hdd_img=${1} sgdisk -t 1:"E3C9E316-0B5C-4DB8-817D-F92DF00215AE" ${hdd_img} - dd if=${BR2_EXTERNAL_HASSOS_PATH}/scripts/mbr.img of=${hdd_img} conv=notrunc bs=512 count=1 + dd if=${BR2_EXTERNAL_HASSOS_PATH}/misc/mbr.img of=${hdd_img} conv=notrunc bs=512 count=1 } diff --git a/buildroot-external/scripts/post-build.sh b/buildroot-external/scripts/post-build.sh index e805bb419..904c4fb55 100755 --- a/buildroot-external/scripts/post-build.sh +++ b/buildroot-external/scripts/post-build.sh @@ -33,10 +33,11 @@ install_hassos_cli # Settup rauc sed -i "s/%COMPATIBLE%/${HASSOS_ID}-${BOARD_ID}/g" ${TARGET_DIR}/etc/rauc/system.conf +sed -i "s/%BOOTLOADER%/${BOOTLOADER}/g" ${TARGET_DIR}/etc/rauc/system.conf # Settup the correct CA if [ "${DEPLOYMENT}" == "development" ]; then - cp ${BR2_EXTERNAL_HASSOS_PATH}/ca/provisioning-ca.pem ${TARGET_DIR}/etc/rauc/keyring.pem + cp ${BR2_EXTERNAL_HASSOS_PATH}/misc/provisioning-ca.pem ${TARGET_DIR}/etc/rauc/keyring.pem else - cp ${BR2_EXTERNAL_HASSOS_PATH}/ca/rel-ca.pem ${TARGET_DIR}/etc/rauc/keyring.pem + cp ${BR2_EXTERNAL_HASSOS_PATH}/misc/rel-ca.pem ${TARGET_DIR}/etc/rauc/keyring.pem fi diff --git a/fdt/barebox-state-efi.dtb b/fdt/barebox-state-efi.dtb deleted file mode 100644 index c4bf99d08649968659d6a8fa427a4c426690c58a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1177 zcmb7DSx&<+5On~tiCu62gi!e)B2C!J4;4S$fuG2Uoz^0oY*%gh=MHcy4!{)Xb zOUUNSSbhhw(G_Hw{)X=-ZI&7;%@b#w`^R3%6Dm@Xc6_PEIQ|Y8C}=34fZ{UF&jBF?WGLwZA?$@`s zZ$KlL+aM&SipBEeU=7xL`0eU~u^$x0Hn6d1XN2sZw`|M{`3A9+W)0pZZhx?7&#Z1NAmMFtD3bf=iv8Zi2lH)^+e}auQUVC|O9& z^69|$zT=0Tz6sM|w6*W|5kyw}_COznRB)~ zfbZAPKPX`fFZ8$EPrKLK*6oqqufZ5}Fg%T_?ok9U$g-#@*!Tw!f7aqKF;vZ&nN(G* z&nt?AOsMEaL;ikSK)G0tb?*S)T^z11ZM~Pste}R+f{}^_!3>s~JfUf-nAW|72?3_& zpIJQ@G-iS*HYde`=4lfO&!kz9jLvxiZ%J~@^3>^`DGSyZ+9;kfL?kJj(WNkU*Tx~L Ls;E=wFGKzUx1kN# diff --git a/fdt/barebox-state-rpi.dtso b/fdt/barebox-state-rpi.dtso deleted file mode 100644 index 733e0c108..000000000 --- a/fdt/barebox-state-rpi.dtso +++ /dev/null @@ -1,85 +0,0 @@ -/dts-v1/; -/plugin/; - -/ { - compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; - - fragment@0 { - target = <&sdhost>; - __overlay__ { - status = "okay"; - partitions { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fixed-partitions"; - - backend_state: partition@22100000 { - label = "state"; - reg = <0x22100000 0x800000>; - }; - }; - }; - }; - - - fragment@1 { - target-path = "/"; - __overlay__ { - state: state { - #address-cells = <1>; - #size-cells = <1>; - magic = <0xef98423f>; - compatible = "barebox,state"; - backend = <&backend_state>; - backend-type = "raw"; - backend-stridesize = <4048>; - - bootstate { - #address-cells = <1>; - #size-cells = <1>; - - system0 { - #address-cells = <1>; - #size-cells = <1>; - remaining_attempts@0 { - reg = <0x0 0x4>; - type = "uint32"; - default = <3>; - }; - priority@4 { - reg = <0x4 0x4>; - type = "uint32"; - default = <20>; - }; - }; - system1 { - #address-cells = <1>; - #size-cells = <1>; - remaining_attempts@8 { - reg = <0x8 0x4>; - type = "uint32"; - default = <0>; - }; - priority@c { - reg = <0xc 0x4>; - type = "uint32"; - default = <10>; - }; - }; - last_chosen@10 { - reg = <0x10 0x4>; - type = "uint32"; - }; - }; - }; - }; - }; - - fragment@3 { - target-path = "/aliases"; - __overlay__ { - state = "/state"; - }; - }; -}; - diff --git a/misc/hassio-os-partition.png b/misc/hassio-os-partition.png deleted file mode 100644 index 5116a3e12f73333fa8ee33c8a10498252e6d2be0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18054 zcmZ5oWmpzn*9AnnTe`cuySuxjLFsM~5CrM&ln#+@q*Gd?yZZ*D@f+fOetf_1ntS5R znSIvYYwdOXqO2$dhYJS=28JjjEv^du9RvddPltg5{$+Pns{jT@3??HkqV8dMlnL#F z+55NO-`Uw)hN(bomjD$-yg+86gTRN_Ks=n79|HyaZNZm-TV<4NlkU%Ndq0P7>3q-0 z`9w?+j3J9QX+NZp`EO@r^mDr0Cv_30&tuHqTs1XpD?FAKmKN?&D53*WS=#V0;3|9I zx1RT01b7ORf4GrbY9?;Mg7Z(fb=+NMD*aROf)OQ=R zmwKm+Vx^2yrZ8aWzOUAOU$2cyfDT_Y1sgw@_bXLiGi3zJHFLsP{e}zY>vujMN8^8l z_+M9oHhVnqWo1-n-$Gt@+py%fwqghh^7izI6Z71_#0DflC|ZJpG8Dxnq{!<1#MnPh zqFrvJ5m!300oO(p1l?8Jj}b}Bhe_>EbdTTduARCPcdigsS6AAV!vDHn?Yz~VjdcinUjfb zngQ;l&!2pXN{wVA_L~j0nUV0NgB6Q{qN54Df(#R9q)ya4e@P80ii_i@sz&7$G>UJn z7>{>bv3IV0@1C8-etdj{K|m1y`0-6aVIiqd_GS)BNJxk*p{$&oimql9$O(iAg9zW7 zn;=Hb$SC>#J-Do#?CK6tSk5X+aPV(2t2UTmsXk)fdhj2t(YeJjleEHtY)T;#iCIww z5+PyXmC-`(50z$7n_s(}cr~x+#3VeMc#&X{0>Ox{2pKfq@}Wy%dR;4{Md8c##fr&L z(^Cs8Dq=xCoU8IGNnBi>Yo*rA9e$5%(EKc$T5EdLdi3?&oz|R|hEY;h6+$%*c|8Vn z7K8b1{9rV!as{&5F*4CaT)a0!)`=DgR@-SEoScf1`29b-&25V=n{%;zN(L0nDPavX zn*QEnX^$vE8Ik=p415767)49Q@WgQ*V0|G#H-_kkRqpnLr}?5-6z@-tUD}WDCLaKcPbD0k+3>doLUdP2 z+;N=y-|d;iK0ZF1C$OG2#=}vt%z+z_XzN!dt91s%7hY|P?LvBpwSQQ^DIGGvMn54n zKhmnA1ufPysVSuYFolp`&}zRw+kBC`LIF>?psFoRRBiWr|{^Rf6{BcfnMXxKeE zGKqF~y+Z+BiV*Ve;c_5LgAw%my7|ril|%jtEyfgb^kR6(-K9#FpsJAX^M{}yrUo)z z&Pv9F^x*+W#njGh|NGAqL3d(*j@m&-N`Aun`GrM3EK+6=u7RD$nH}pGKX$P z{0&|_&6kIIGpbYA!4W&lp{iztV4m)HC z@n|C(&6vkO1?@~^?^C0j#l(FWLH*`pVv*qj>-&UR+{(!+=2iSmB&F4`R@+xRXoR1o z{aB^DEnOKQpptBWmj zIjC;^mYl&1(v7{57TZGR)mCK!Yx|k=rpnFrW=tn8v#!oGa$O8`7MN z^lO>27RL)wGt)wZQ{*k0*l7N(56(%Xpr2qF+#NA|+$p2-beQljrP zA^~ny9|=ALF{d*)N#)hpC8Ws>LMjG(4Qb`qFB3>OCmbm)M zay+{C$gi)@B|G}f45CPcn2znuLkp+t32g^c-61>URwwor!@5**DJ_Cv^O1B?oT(6VsuMISb3vW}hkwdxZ%vi4gCWKj7 ziP7x#F=EYN7&0GaCuAvl&TOccTUfrWV&u?&hiF#m7Q{g&r0`Ja#gSmXN|V*rFda!< zq+O6UWWrFE3w<}D+U1-w*@1C$hPt2Kn+9Y{%O*e8F37Wb*33Y~4+e)7Yxn$)77LP8 zK-KF&y@!BEtXpJry?77rYf$7v8IpRuacDX)DjPaz29zOhA;d^gF!YsD$&lb+T|Xow18LfkXOa8eyMjMmlHPu zQGv*-lFbaPAtRcw*}a+27;@c9OA>d z8tDEg0x`)x7LD(Vi~5^8*v0a3U*6LypC{QSM7p!8FzjU~3{mpU^-|vbQOD7$h9@B* zk(QTM?pWen9pr3*)r^pt3o2UK?CuVVO-X?(iXXviQP!3Yq1SX<85C@su?gv3>)c8< ziX!s62A`Xo+sCJ2pF?!_7Vz<{fPqC6o}!!x6LNsu+neJ~%8L9tLjRVZIHt3)t;&eF ztIISdOiy}3M)BBj_WrX`wF z<=Wk|FTmlw-gUV!sQ=MIh=vw+Sk5mEYhKpc*oYAlB2l^w0u3Cup@M^hH?D_AUEl23 z4h#-zxE+-!Qv2)js2eIsn!5|~@xjM%8#Z8KCU)r-LMC$ea(oOHa%(;+K&SgQVCKBM z$|$sz-u3rr;eCIU&?4*l+MpXBjfg~uo*yokU04uwyn37J@*=C)GFUX&(40C zVR5sot4sZDNN_MIJG(qA+E$>bk`ktH6ppH=Mug_J9Rj}qtgMJgpvlG_JUo2aL*WJc z7L|F`XuPqqS60>}NYJu`{ah+CqX-!ZNwY&n`GeCm*!Je8`b?Q-$8l0i`EMW3?POdq z1)9gwET-QbTpxaq*!E|#Cq7kMRA?~p@UACGq7`qRutkwvSc$)!oc^7B4i?14u55IH z&8p&9${|oW6)O_c(8wsjl+3DH1q?owO#6_2H(S^U_}nO6#>~=bt|tAEDZ;K0>72G* z7kg7nCw3Ff&o?ba_qf?guJ*dLncto!w>HdrdhiTvxpp-~whsta{O)h^pzT6E8xb&o zRv3D{digf-aLu>(R|46uGMxoWJ&;ZAT*H=%1L_*I4L!?vfUg=AdS;@DB!sq zJRKK9UQ5*aEg~*H9Z%$QiaOt5Klbtyv;8uExz0JexW4{ZpS^Edjx!osEX2SF_+dt} zg@~dB>LK#Xhbf(U!xMLBtBBs1K*)Cnb#@~QeSHg$CG4_4E%_^h2f1O<3I63LFd7(| z@WzL~2b%%l`7FkrU{F2JgDcANg8T5hJa~7etOlRQ2}1H~vE50!HA`T#;_94bwrj`R z#TrX09+Mu(uecngm27Juwm=(5PP@ghSTZTmi`@woBqBk=e5q&)aiFaBK*?b!t!z2w z4J)fUCJsd=3S}|vV}2PnKDUE#1yQ)&5@T}r=g8ha)uykN>~62oytsqB%4gSlcST}$pOqtDYqih_#^=h%yByZQaS`}@fP8H6xcW^g752Ho0# z-9Ocds&RwyRIfJx#`Y%9sH4(pwNr(^rFZ=&qzy5%>%MxJ#VGDjD4}k^f_+CO2~ftb zN~{|FYepocq?Bzx?UDm#0{eN+B05L8RuE9}@yY*PbyQ9KFqeCtGweV-yGHOXn>yKf zoRqK4-+_`phd1!?;qJU$j~+vQ)eN$-X&V>D$jC^hu;V#4NWnSYF6M~5NsWo=eBuGc zft?y!t|7aNO*I8tpXQ#J1Zm)}Og=FL9A@G6hrbIWp+JP=!no{?gPSb3HaQ(HdOp1< zaA+KgX8pIGed0;$IntYEFi1n+OO0`lnEEMxBD<62HXL><6u*BD?sW(KH_c-=19!b~ z7G`GT;>nB#vkVsJM{4J(@824}8k zAqOBby4M0uudb4T6yfjtwqF@CJUm>zjNj+l!R2Tkll+g7-wj2fLb{voPD#ksp^S9# zo^wbdofh!5B)>@*2=tOs62HPe2}SxG?p_S1q>Q6Xhd zAwjc3R|G6Zbx5rx+%z+XJWE;{Y;b}M5th7-y;NY|N_LCD2ru5F;UY`4-RH*1^&Jhw zrSe4}{w3P9_w?TZO*OA_@*=8Ep?~*mw||cg3>{Y*?1=#6RAdU_#nwhz@Rf@nP8$T0nn7n`i6i%};hCv7qmKwmrFcYiLOtB6NjFM;MZ zpjcxWoP#Ih@TjpEC7*&v+)U#b%TdY}w9K|4kp9_1F${` z$uF5c<(g27%$#o6C~lJ!;rI(?+~x6y`S5^+36)H=?#I3TjOwjmMpTGseo)xL?J=g7 zK8f}Cuk97L+@c=UQjc=r|GS=;`HBt1KoH&@GT-p>fc4>RsA zN~c*KV71s-?XwZdHSLc4l*_mk0}NH$4k}xSMMXt7>uncM2na@B=lssH+;|uOJi3J2A1OOWV#JdnsI{00&WJF2G;}raSo&+%!m6UBC ziEjNznt#_D$gg1a;|D7T0;+)5MU0W}CFT>b9|1%aE4=ZM(ArM%?f90l;+wyR}2 z>z~1|2bko0(>Okm+m<|MTXfiq!?`ym+asw?gK-qE@WlS%H-ZTuy@3+74Bra_=szvI z8cxS6a&f$*=l6KC^FPRXw9HdT=ZyQ>`UI7$;t&_Tm0{uGaWphEuQ!s<@ZbvWUW@Vc z{14`$XhdO1=xAwip2Q9g6lEfVRC&tOv@|$>fB(-UX^yGW0&;xZ1$-9bN$N?)e*HgR}B5 zmTQ*rJFJ53&y@AQWE*DxN1v-hO)oEAA79_+Y-I>ZDW3wCJGE!#=*V*6CGeUkDjJp{ z);2cC_Vf&&)TIpR0D9^&78wx{@bmZ26F!>G6$+?*F{!CKuhSA78rssp^RSyAExZDX zyE;GTGuNJeLqSeX-C;RKc(~Mp*W1gu>*CeZ%OURKf88?zSRh}7laH@KajGcs;83h1iY8o0zYin3pSy|d{ z6BME%HX_9$bj`B2NTEVNU{wAt0OG79C8LxKY7nT1vxX?YsiQNhTVmMsy9f#i5v8W4 z(%L6THDh~@!Qy&ZMo&^G^=p=0s@FJ6o<$MxX;LuRHGK(Hgnl9(w}{BmV6YUUwUbZ? z2}Gr2v>#MdPyq$bxLUi^Gdw>tpZC(Gc8}DSS;|SG%JAE_Z-F4;tRcBe*()-}+EIIT zbqsu@P^nD3L`9f3Lnb_Ss~lF*M42FuW){!%$W{ddX^89?2jSlQ^cH=_aqYtLa(x24 zNT}^KOIC>zQhnQE6vxS5<(#lXPm`p8K_+=!s8o+mhnW^)V`JaWUwnm(ryVq5>9(oUNCXB{$nCNl zQyQ_jh>w{(l#rYpokQ%u6%_O^(ddY=zM&SAc@#XQ6TH5zih+q))|@MYgJ?Qm4IwA-t5YD_~)!>UBXq;Gylk?SS9BojEjZ{R$Wy!?p8q&o@1?G zWm9HV+OT+n*hpVL@7R$GxV%@sqeBf=6A0da57lPXyb>g3 zWUMjKo7>CFF&-bmkJ|#G2?a`Z@thzdbzN;j_yr8aL&&c=fUMLnt-{L6nm~2*EygRf zwpJYs4Jnifm-8cns;cVOl#~=TyWHX~0XH=}j&3OX9nkWgf`6bK?BaIeGqxx*o~rI;d+r`P9ZJxx#&ZP4XDbcNSK58g z03KqnzqJKo37n!F&y#QtOSfy5k(82J8>Gtq?+O6w1$r7CH^?g@#v58+XjzV4LnVq_ zGGk(k`$<;>Q+v;IA|qwC7_kbYQ7e?zed~WzH~R{mUYGmeEG9iL@6gb`ZVk`HAj`p^ zpHhxjENC1D-f3tVgaCoeLh@YwyX;NA%hRedbm|F1#o=)xf5BPdP^4rrm%~3QztXvo zXARs5UJozS+mfWQTayAAPGk9JY;O>digJK573Fe&CSK_An#{!1^c@{8`$wS@ z;~hT{K7i>KkGWgZ$-Q(im`(d!S}!K$jxpWm(KQ#~Q=Z8TC9_Envkz#n$d2zgoy$M) z`*&uG7aj_5E93sCl_j;#i%(=icGW&lEc&>~lGM;^&pd0%yK+ZG4 z31Dpl;s{>mx7{nfp{r^|%Tp^-1QlibnY_%Z@!_9pls50HxNQH&x37hXlE5WKPcSU{ zCXj@mqlN?J8Z^vA0)>D>yyACf3*`b1GhP?~3kz%WbKj>K;JU<&j7R{R5y)<6BA+U( zLu2tcHNLq$_~^DKI(@p5OI|>1wjbRdX-vWMpi6mvWCFa16F_;2{9Os!O(n*PJB|(g537u``YkJZ9qnRr*`J zrg(uLXB)p$;rH)OI*?f`MsRKpYsRuXX<`vTH5#i2#ZW;dWMjc{QBj8ya@!w9cvHBU2B3La;YrA9}xF}qAyK{Rz$ zNUw{%*{WY9y1KfN(ZX40Tp#}^bF{erApBWF1$>zr zFW#xLWzQXguoAVRp?*T|L;0y<=UGqq5>CpAK1ki@rzBm%GCa6G%SoBrPpyh@TdwQ9 zxSqAy6^6?Y9rljRV&I!xvSAATz1Yb<5B%0mqeO466yullaGiY=NYBn!1-GI z1;OjSjW0GiC%#vCsqR)&Ewchsxa_kE-o1OR_bmK+0r7=?>g1`Cy$E>sVzY4`d4DU>cbXzE^E9w z5Q_qcIk5!{&qN~@%y*lZ&|?+6$>YrAsmv8dgtTkkqYUFa!DqC?U-Cm^U1MWPfJVvuqWSq; z&S>S>SBQ&?2NwufKEai8CfL!kv;~v+RH4FFmVkE(@^k7K5Jd2ts5X^qay`&|C080{ znlyOq|7DA(H}*i){$U1NZ@+@XVm(QIvl*}S`g(x2i16jh7ZihLmslVdyiy0SqX(d> z>kwwQ8W)apd`5NvT(|oYzu2@aF=i@KJrRh`2(URy60vHa#pM+{Y|P9|4x|Nsn3ydC zuT7xb5jzHWz{JGF6SDwEh5+D{XL{QuFfh;wc!AyN67=UZ83a~Ag!GOzxSi@O`Qp$O zAf(R&188bGHGslyLUt2A%qP$zpr21&9(UY@T5B3VHw|ZIXycIL=pA8 zJ=z19+3p6q6$wQN!IUQmLkLimnwpx1cDA+xEyilU=X{3=c?)!)kASX3;LjYbcqmDb zk~-s>hk=&3~nz4 zC@87=68s~2^BybDuFD3oWs_+i2V%)+$^B1_N#o+;bGdM0lf2X&i)tgG+Gx4H$&d`b z^&Eo!mOq2qOYttpIV-DuH{a)XnHDmj%g|0o{R^KcnWpK@^&)la_vJ63@1DrFmURn5 z4mmb0ld@7V!cR(0)=CtkYtUqbE8*8N^rRTI+cO86>(q2~6&L3F>mXJ*y6E9ylm%iW z=#34LY-`vn|DmSnnSZn&QD&8Y*3aPs9+@@eL_C;(0mRq0&|Sw4opx6e$__9YzxWfV z*D5Z0d#UM1q~42w>r1?)rlnUGMd|Qo0-a}44~$8vsDR7rGh!rTxtt)x&<TpnrlYG1p%n{1s#o84Y`{lMhlf&;JB}d*V`Bw5U)zG;@$mtiH#2&u zDv2n50->fCB4P%jY$m)>GSZPdl!T)U?8r2X<~9p2FH}iMNjP0Gc+&A_ZB2DTE%jpO>T1N81P|rJw(?qx z%5@WUb!qNH&Fh;5R2(ZQt1u#5t|$>*T_g~^J~chLC#|FkY6xSa{$>=J`#d;oDx>*bAIr(7x8acF zuF?A1OF3{<(dJI-m1}5@ma z5S4ezyl8Wa2-%sbwP_$|`fnTxq~~!t}0*0b3jb!jcbXn948zG-2e<{*EON&z;zF6Gf+WlR_lvJgw zH3J_L^SCqNN!zqlW>{%+Q{t+}eRv zZVAu-_Hd+?Z8G13s$u=N?KsKC8j+Ailjg{hs6&r|@RGM~Ye#)pFL^`d4d;HnAPNxm z2?s*AG6KUt?mj>ikdybMLBycMrF)#Bidn!&&X}=i}T+(`%JO z47w&(-T8^`#=W#*lG}%sNYG#%p5n+lT)orR_U85v?8DpJfG52vn8lyiiX?op$I+8PI>0{wUkDPBT~kSAf%6x3lZOK(t1;E zOBs7zMTyn!`k%-j0wf;uzHW^O`~3_U8^Dor`XT(~pqnafgIO;OSjHs6jz+Dw3! z`O&;WbQZXO0}-2=T8Z_>{p3$2)Wv3=$$r_4A+4BKnl}prGc$}=8?tI#yav8* zK5PYc_b&QR-UDa7F z)>1q!Uh>uZ9N9tM8M@b~qLrfSPS?%tRlJ4%h~zHKPy|wRmp-7cwJ69W%guEqNuw`b zU*E{bT9<|`xv#a*P;Ro2I3QPN(o8p~Fe-M1YfkRQZb!OmM!(Eb7jhApNgmcH{;f6b zsDc_k(?p7M;gyh>Smug3^k#-&EAY`UuhP+o2nQwL>sJIE>k9cc0b^Br^zmx%hY^IJ zK?I`?u-;&hW%c}G*?EFinF0gjmv=EqxLOKOhD-rQ$Ph&hDtXTaLXH6{*^6GTn<5*PEf|2!y6UypI z0MXL$EK*B%-Xu$EBn<4Ol&)^Q_qV2$W$GMEOE0|~@o#GK{fyWq`~84<^(~fHWVdJ) zWYfX4Nv>8ff`%Y@4^gPb%2delc*UhYlhE;DYqC}B>KQlat$k?t zX~ROdoOX5P+Nq-)w!V%=fnD2WlqY&s4HqFNe1=3$An7MU0s_ISOD~V6Y9|(JJb(!a z!32pg$;J8IFL)`Toz|M_$XXY7(U2uLCYQ0&yIID-iIQkwz)}X5fUwvOIX`UKbFruQ zB34#5o2Jf5j}54P)JPF|Uys%}eIb8|t1^={M%X{kIKK8?L|Sgl=?aA~ygZ6-WiKBS zlmjL-b1fbcO2SKupt6<=gK*kHUL8LfTz3ThzCowJ`Cmh_8A+3}{OU)T%}rj^sWYgs zPB5X=rh|wYnTRTLh-7l`{mgWI4zN5!s~G;l=>${rPwbk`1OAN1td;jkHqfx&<)+-U z{lUu)BWzFzXuN4A1TF0(8O4Qcin0XOkeu#32H|j;6ZV)_qz@fsH*1AGD=itFm2J@D z-s9q7e{ItSZL?duK0a9uNQGr5-3QFV+$z$BjD$9_f+>PwJlF!5wT;+8+npVub!nkJ8^Y7N+ zidNa_N9@3i9&5qIiqPqut78H`;PU&dm8BaHT+po{AY-A4^jXmhCHwIN+I6XWs^4_} z`aQ>Tk=87d##LLe@;_UNIrQwXGCSOEChjb{b@D%~|_7E%xQjN1M>erdyw^!@iUk1!oAJee=k&ww4u()@v|aQ0qN#>own> zh*)NroIGtGJN#Bwz5CdLim~fo8LquENz$&h>_R23|FMAow7ZWNdQ~4w`#_?WQ0z{j zOMbpI31;2=)oiY_ zZ;igWiqw$3-AXbltrSW&uaL7oQj(UOP45>Lmk1t8FcPekGZ)%1pCJq+yuZq%;@7-9 znfO+E<#8S~Rz{d^xbz*in^HiVf$71^MP;b=_FF?4;`9e^@%)H|`j2^D^!t(9mDfzi z_&#L2g7?L)e`oOhncouJB8S4j!^V|#oF{*=47xBAfEB=sjhV7zJNpuvfWl>~PEpOgEw%pos$=*9Fw@cx91NDK)O(MF;4~B3O z8?4NM&SC+7muy_NMo}b#L@bUUMQ!nho+RZB$RExil!ZMnn6h4a^aj6x7~(6&g(rQ( z0e!%En=J34?$}mw@7zH5>ywM=sm+Y;=PJkqa33h3B#0c)l7PFgc#9~P6d9@0~R8y)wFru_0wcMLe4O`)3cRx2a z_hk@Rv|><+%I-JHF2f?>ET5&C0&@1Zt^UI;Va3>8&!-U!Z=d_*@rnR>D)oL?3TB(> zkG61%Fb9N&tO+Zw`Fzw^!j|TX9865gD-5Li)anE0%VW(F)&=?c$t4n<9*XnHlKvk+ zYJrAX`a)ScN@>2P!Ny|Cyc?UITs86#SF&aLZf;=YmxP5Kp;PADAs^;ca7w=Qy*<11 zZI`x%i9icv&0-@|)ZBrAflm{{oU^_;RkcuZR})(E+Efc5v%I;FtR(#G+Nm;yS+Vjs zbTy-iYesEeVpX+ephC-1)^P#$soxlJbJkuIS@NPp3S&JJ7YOFRQYxL(D=U?^D`}!E zWYg$j)bLpo75JAdYAW`*w)(Bc%YM9zgu;xIIrv1HoF~HY&Oi=|@r${l9pMk>Ob4uH z<7%Clw6rzJLL3{EFWKn?fryB(qMDlZwD4!7EtgPjN;AHLg3W_DT7`L2tgI@kK8qP_ zscvr8lv#;1r)bxAJj%+-kfD(vdlh+n&a!oR&!U(ik*)mJ*==^V6%4M~J#~wpdwxAt zUpK4DnHwzJ}7S(*zq9tvPk`-mm z*fb;qaCB-j{9$0DMNs5n(H+mK1GjNq?1VQfy}e3qRd&^nP({o=O=kC*xJ>6UXGjVm zCL)O;LXTLu!5zL#Y6q;GoE$KTw{K6+ueyJ&xRLPD;Wf=Q(GoOcCx%W^j+3`W;))Y< z2;f2Gi@>7KIWoCnk_mNyX_iSOa!_-lFz9l22VMs`Z1b$SZ08eqph!qagu|Y(#%4O# zz$&D13U>vXeFHNiYO5`P#DY(p$iq?AIYPo)$K~i;7P=ziqQdrUQq(8}tPYsboZiHI zr{n{Gp1|$GEjB0U&I_Mld)~P!91P@nQd$U=YL$I%R$f)u7*;+59qcrd5?}?a`FRjq=3B)%E+w(bR}KqpR8gskk*kBj zEY##UI`2}`3biC=j*CKih=s;r^Cw{P2VsI@`8gOR-QSqzjTd{w->VRwJAq;{6GIM1 zK5p$bOznxc*MPCG#Qr(odF+@*H!|W2j$W2p_PmmYgoGxc=Ee~r5gCFGg(O=gx);j@Q2CaEPUyn^gmyN(B zwuGFVY~o~$Y8f*Xb|q;t8nY@SsKDxw5h2jm|G0ZetY7Th-N%WeVQ|Q9a-PT|bj)h?I^s4NfMn5PSHR_*crglom8xIl0lT>zG{@a|Kkz-o_ z==3|KGlcBB*)O!P_oknRps@rU)|`I2TR;E>1-51f7>o6-IL}%;EVd&j&jtRxFTMjAWBYMd3N3TE^G(K{Db8o^(7Cn)J2qIc;9Y zVl!g;!-4 zsYnBCfqDnapBl|iN1fKt;a}Td9>;?_#Jn!;`t29Xaw;{BrBAC%=_8MI`WvUS>!;vO`E0QX^qkrTs<3vf?OM|4~dQ$M)oDjp!Ud2yH3~uw=*zA@uct zOL;C_aXdzafsJs)O*TtvR=zqPUdM}9*$m!g(J<)VF`x7C^i}g0B)Ag=IuAD+?L-Mn zLNDoRyiEZaCTN1#U+yt+4%lb~bT=4BD}!O+VB=N}@6%oasGb@dztGrh1VEw>mZJCE3>i&rIx0ZEHS+0-htS4%Czuof= zC7<$Z+|-Vu=}ULvdS$z++UHm`?90?~lDkq%`pffHyWItQ;LEbi<+Pp*)SM7i9j8!& zUIzqWJaXFu3nw@u18F1^A$hj#`SJ|mjFyeuG~cbiuqk!&-h)7j(s;k~w<2yk5jQto!eKt^Pby-#sg z94H)JFF>5c-=w|lu@L#XOyqGLxq5=4`Kh6!P2LF7lgQ^#LNr`HVD}tS)NIA@*;$GL z{hDcE;~oVvVhg4$iqNlw&xH@L5Vdc8t^z~Yw!X7;zgo~zSiRtSM&7b*owjJpXp5!@ zD?nPrjrP1dw;YJwkYvv7_#&*RiDV()O0-cFC3UBmJmWPRbOv4Rbz?JP$dC6J_~@^8 ze9gHGNtkuU+;h=1wOI_CpYm%(JRot?9>O=uuEyul>9Owtznb5gwUQJ&>6b5tefvG7 z)mjp#z?4_qk)D6=DPE|SLC5ifYuJZr;Y&`v_W4hh0xjzk8gj8H{-?nnR0m%kqnu_! zyp`=4k9|)KJ$HI0TytBo%fBiK)kE!->^1s7A{;K?6rs7Pehv`!r%$aB*AcWEF9x@A zkFpiA)jEqJ6x6+J1op%keBiI?_4zrZfo*qxUy5zT;uwX`AI|lO+X%Drl9UUfRU}fR z)!%zL*((uw`EeDJ;*2ofqYvmH8*%I?UbS7Gh#=sxssBK{I)|S3Mp&;PpC0DF+*Q+f zm($O3k`LX_$ zqq02p=2~IC61ZTCTWJ^T-~DwC`+)yHL*aejdz8p@&Ln5T)JP-)-d6}&{B23xGup67 zU)9va<@NXA6+4+-FU-QQ81x42uz#&)1wY$bR_A{`kdWq+Zl%p;Z?nKgz&yo%_Hb3; zcfLbVO+_~75bNcb(!6`btc*5iitrI+b6qPODKoXQU&{gB_6v|TvmZgA&T=dIogUr2 zE*F=u1F(r)XXu+rZ>HzgAkYS8+-42)7Y6!xk}JFrCIh=9PJh>R0Abk_ZBUQ=><>#j#paW0Z?~%?6N1Z#~wyq7kqr4+{nOx%2xzO}# zo4t4xzehjNo|abr(U$G=`w&8Mw%-UYdz~@Bv{V@|K8}%IwAXXJv`{`S-yX-0sh^) z-|j0OYgWa{4>RV#d6@h5BX@aRPh{~8i^whSf8NP5FW2sz`1iHBFTqa~`r_T(_E$Yu zF|9B@|1Pgm1pT1IcgiYbKCBoHzZ4OtmpewL+dZi$ZMTQ3v=y&K-Uq~GEx)HmCi&o<{%Z#CS`^ zmlTJZ6J4pvc!PXGI|f*pfc=UBgXv7IqAf!!jFwDUqpw+Wl8tF&=3hI)M4OU(lh@L7 zIRHf6PL^(jyOAe)o`1K)*ifCj$1IyEy5sa{_ejC3L}c$z=Ytz3G}ABjNIC0$+<= zdyTXROD562T=6ikwOo)8Q@MDVTgCH&A%w(Q6e8;Ne1{T=+dou-JSrS5xbzy+glW9c z76vRm9KOv1?G1}x|FvBHd%Y-2yB5ODmqmQa!qMrz)_eTwR`3}SY)s>N9kvQYr=ug{ zkQp;We=YI88r%7sE@TexeDP9?krL^QeBc=7YhOJW9@e9B*P#4pYbIm=o7=)!pdISl{OLD`L!^)i0u{l` z&9`78i$i0^QG%!8C8VvGMGrz~{duGIs~a1&2Z;vzZrlK?^MLfQu!$%sB|;k>DJiXJ z9PzuaP?wb7(I#czYlt4?Yjxpaz6&%>O{He45(Zq;ASdV8)Yy>kr_AEw62!Eea4eVk zsIvvRpAzFUBSuW$(JH!8-hBM#adUG++lEz>kDW7wcvar zSE7s(*z6fNVHP}Srs}2+ST{yABTD&!{fX(_g%&$*50B83QH5o96Auw^5ytL+-UDL4 zgZApd2Z@J24*1gCpB5K=xHChjsj0<9{7CTIkvKe2(Xc*+4LGoWSkmV};Uyvhc3sj= z?@=rD``=yf8b1?lXb3$`-NG)DWcVk-%0GGseN7^8q^;3Z95}w`qrQ=Y&bxcT+e^Vt zFaFIkk2S5N)gq<%FlnP>kAJD5y!?=9D`fw?bJ+v`PjY~O{~>r?)U+`qBor~=X#Xkl zGwjP35x^;0ZQ74SPDx41M+FZ!+CxI@1bZ?e`DiIs=YB6%`$9+I^X6%zo0g42khqj0 zfx`kerT+_^0Al~NZruVqcI-xOZZ3+8OH^GEuhNoIGX@vNF2S5r=ilQ1+A+oC=;2gk9LrF0>T*tH0;6N1Q7vTQ^_vsrtGWWI) P00000NkvXXu0mjf1iK2l diff --git a/misc/hassio-os-partition.xml b/misc/hassio-os-partition.xml deleted file mode 100644 index 180d1f6bb..000000000 --- a/misc/hassio-os-partition.xml +++ /dev/null @@ -1 +0,0 @@ -5ZZNb6MwEIZ/DXewUwrXsE176SmHPU/sAayaODJOCfvr14D5Eo2EdpPdSPUF+x2PP553ZOHRpLi8ajjl74qj9IjPLx794RES+BtiP41Sd8oTiTsh04K7SaOwF7+wz3TqWXAsZxONUtKI01xk6nhEZmYaaK2q+bRUyfmuJ8hwIewZyKX6U3CTOzUI4zHwhiLL3dYRCbvAAdhHptX56PbzCE3b1oUL6NdyFy1z4KqaSPTFo4lWynS94pKgbNj22Lq83ZXocG6NR7MmgXYJnyDP2J+4PZepexbtbbCZ73t0W+XC4P4ErIlW1n2r5aaQdhTYbmm0+sBESaXbbOq3zUZSIeVE39mWJFbPJJSlW3yg0QyYKgRzy7pTojZ4uXrTYOBn6xJVgUbXdopLoH1tuZIM3bAa/SW+0/KJtZs+D1xNZcPSI1fbcWi/xhwuMB+sxVIBR/2XwKfIpiyn+Fa7wgGjlP1n4Dfg/bzgXdalwcJrdwyl3Wp7sOTDzAyXfQwH3GtxFwcCf6UF8Q0siK5bEHxjC+J/aEH85atTGjD42A7c8xki0UoHbvHu92tMLFD2NhLqR8Kdphiye+FeW/C3ePaDYIGbg4FHYs2fMOKb+7CmdG1p/wFsOxx/S9vY5N+fvvwG \ No newline at end of file diff --git a/scripts/update-dtb.sh b/scripts/update-dtb.sh index 05c56deaa..b4eaeacbd 100755 --- a/scripts/update-dtb.sh +++ b/scripts/update-dtb.sh @@ -1,10 +1,5 @@ #!/bin/sh ## OVA -dtc -@ -I dts -O dtb -o fdt/barebox-state-efi.dtb fdt/barebox-state-efi.dts -cp -f fdt/barebox-state-efi.dtb buildroot-external/board/ova/ - -## Raspberry -dtc -@ -I dts -O dtb -o fdt/barebox-state-rpi.dtbo fdt/barebox-state-rpi.dtso -cp -f fdt/barebox-state-rpi.dtbo buildroot-external/board/raspberrypi/barebox-env/data/ +dtc -@ -I dts -O dtb -o buildroot-external/misc/barebox-state-efi.dtb buildroot-external/misc/barebox-state-efi.dts