From 220dafdb7243da3683b8a972c80a3719c2d137ef Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Wed, 4 Oct 2023 10:18:08 -0500 Subject: master: subtree updates oct 4 2023 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit poky: 61531cd395..e444d2bed0: Adrian Freihofer (3): lib/oe/utils: Refactor to make multiprocess_launch callable without d lib/oe/package: Refactor to make strip_execs callable without d oeqa/selftest/devtool: Refactor runqemu pre-requisites Alexander Kanavin (69): cargo-c-native: fix version check igt-gpu-tools: do not write shortened git commit hash into binaries curl: build and run the full set of ptests ptest: report tests that were killed on timeout perl: use 64 bit integers across all targets perl: ensure all failures are caught strace: parallelize ptest strace: remove from time64.inc exception list busybox: enable 64 bit shell arithmetic (via long long type) openssl: parallelize tests openssl: ensure all ptest fails are caught glibc-tests: rename to glibc-y2038-tests sysstat: merge .inc into .bb sysstat: update 12.6.2 -> 12.7.4 glib-2.0: update 2.76.4 -> 2.78.0 ovmf: update edk2-stable202305 -> edk2-stable202308 libdnf: update 0.70.1 -> 0.71.0 liburi-perl: update 5.17 -> 5.21 python3-pygobject: update 3.44.1 -> 3.46.0 go-helloworld: update to latest revision gzip: update 1.12 -> 1.13 procps: update 4.0.3 -> 4.0.4 screen: update 4.9.0 -> 4.9.1 gobject-introspection: update 1.76.1 -> 1.78.0 igt-gpu-tools: update 1.27.1 -> 1.28 libva-utils: update 2.19.0 -> 2.20.0 piglit: update to latest revision groff: add a patch to resolve build races groff: fix another build race via backport systemd: upgrade 254 -> 254.4 util-linux: upgrade 2.39.1 -> 2.39.2 cmake: upgrade 3.27.4 -> 3.27.5 jquery: upgrade 3.7.0 -> 3.7.1 python3-setuptools-rust: upgrade 1.6.0 -> 1.7.0 vulkan: upgrade 1.3.250.0 -> 1.3.261.1 libxcb: upgrade 1.15 -> 1.16 xcb-proto: upgrade 1.15.2 -> 1.16.0 boost: upgrade 1.82.0 -> 1.83.0 btrfs-tools: upgrade 6.3.3 -> 6.5.1 createrepo-c: upgrade 0.21.1 -> 1.0.0 debianutils: upgrade 5.12 -> 5.13 diffoscope: upgrade 244 -> 249 ethtool: upgrade 6.3 -> 6.5 font-util: upgrade 1.4.0 -> 1.4.1 freetype: upgrade 2.13.1 -> 2.13.2 ghostscript: upgrade 10.01.2 -> 10.02.0 iproute2: upgrade 6.4.0 -> 6.5.0 json-c: upgrade 0.16 -> 0.17 kmscube: upgrade to latest revision libarchive: upgrade 3.7.1 -> 3.7.2 libsdl2: upgrade 2.28.0 -> 2.28.3 libsolv: upgrade 0.7.24 -> 0.7.25 man-pages: upgrade 6.04 -> 6.05.01 meson: upgrade 1.1.1 -> 1.2.1 mmc-utils: upgrade to latest revision mtd-utils: upgrade 2.1.5 -> 2.1.6 puzzles: upgrade to latest revision python3-dtschema: upgrade 2023.6.1 -> 2023.7 python3-git: upgrade 3.1.35 -> 3.1.36 python3-libarchive-c: upgrade 4.0 -> 5.0 python3-setuptools: upgrade 68.2.1 -> 68.2.2 python3-sphinx: upgrade 7.2.5 -> 7.2.6 seatd: upgrade 0.7.0 -> 0.8.0 sqlite3: upgrade 3.43.0 -> 3.43.1 tiff: upgrade 4.5.1 -> 4.6.0 vala: upgrade 0.56.8 -> 0.56.13 xf86-input-libinput: upgrade 1.3.0 -> 1.4.0 xwayland: upgrade 23.1.2 -> 23.2.1 python3-setuptools-scm: fix upstream version check Alexandre Belloni (1): python3: fix SoB on patch Antoine Lubineau (1): cve-check: add CVSS vector string to CVE database and reports Bruce Ashfield (9): linux-yocto/6.4: update to v6.4.15 linux-yocto/6.1: update to v6.1.52 linux-yocto/6.4: update to v6.4.16 linux-yocto/6.1: update to v6.1.53 linux-yocto/6.1: update to v6.1.55 linux-yocto-dev: update to v6.6-rcX linux-yocto: introduce 6.5 reference kernel recipes linux-libc-headers: uprev to v6.5 linux-libc-headers: default to 6.5 Charles-Antoine Couret (1): systemd-boot-cfg: add .conf suffix to default entry label Chen Qi (1): python3: add cpython to CVE_PRODUCT Daniel Semkowicz (2): wic: bootimg-partition: Fix file name in debug message uboot-extlinux-config.bbclass: Add missing variable descriptions Deepthi Hemraj (2): binutils: stable 2.41 branch updates. glibc: stable 2.38 branch updates. Denys Dmytriyenko (2): bitbake.conf: add MACHINE to SDK_NAME spdx: use TOOLCHAIN_OUTPUTNAME for SDK filename prefix Derek Straka (1): pypi.bbclass: Update the upstream checks to automatically replace '_' with '-' Eilís 'pidge' Ní Fhlannagáin (2): lib/oe/package_managegment: Add nativesdk-intercept PATH update_mandb: deb fails due to missing man cache Etienne Cordonnier (1): bitbake: bitbake-worker/runqueue: Avoid unnecessary bytes object copies Insu Park (1): bitbake: data: Add missing dependency handling of remove operator Jan Garcia (1): insane.bbclass: Count raw bytes in shebang-size Joshua Watt (6): classes/create-spdx-2.2: Add extra debugging for missing package files nfs-utils: Don't start nfs-statsd.service without exports nfs-utils: Add StateDirectory for systemd services bitbake: utils: Add path_is_descendant() bitbake: fetch2: git: Use path_is_descendant() instead of path for repo check classes/create-spdx-2.2: Show error if document is not found Julien Stephan (1): bitbake: bitbake: cooker: add a new function to retrieve task signatures Kai Kang (2): goarch.bbclass: not compatible with riscv32 adwaita-icon-theme: 43 -> 45.0 Khem Raj (25): perl: Add packageconfig for setlocale functionality differences libc-test: Run as non-root user coreutils: Upgrade to 9.4 coreutils: Add config.h to ptest package gettext: Add missing dependency on gawk autoconf util-linux: Disable failing tests on musl Revert "util-linux: scanf_cv_alloc_modifier changed from 'as' -> 'ms'" util-linux: Fix lscpu on musl qemu: Add PACKAGECONFIG for dax llvm: Upgrade to 17.0.1 oeqa: Use 2.14 release of cpio instead of 2.13 musl: Update to latest bsd-headers: Define __CONCAT and __STRING mesa: Update clang-17 patch to upstream v2 musl-legacy-error: Add recipe elfutils: Depend on musl-legacy-error for musl targets debugedit: Use musl-legacy-error systemd: Drop two upstreamed musl patches systemd: Refresh patches to avoid patch-fuzz glib-2.0: Enable possible locales with musl for ptests glib-2.0: Remove failing ptests on musl llvm: Upgrade to 17.0.2 createrepo-c: Fix function declaration bug found with clang mesa: Simplify llvm-17 patch mesa: Fix native build on hosts with llvm-dev installed Lee Chee Yang (2): bind: update to 9.18.19 cups: fix CVE-2023-4504 Markus Volk (8): mesa: upgrade 23.1.3 -> 23.1.7 libportal: upgrade 0.6 -> 0.7.1 appstream: import recipe from meta-oe libadwaita: upgrade 1.3.4 -> 1.4.0 maintainers.inc: add missing entries for appstream and libxmlb libxmlb: import recipe from meta-oe pulseaudio: dont include consolekit for systemd mesa: Upgrade 23.1.7 -> 23.1.8 Marta Rybczynska (3): python3-ply: add to nativesdk python3-isodate: add homepage python3-rdflib: add homepage Martin Jansa (3): gcc: backport a fix for ICE caused by CVE-2023-4039.patch fontcache.bbclass: avoid native recipes depending on target fontconfig multilib_script.bbclass: expand script name as well Matthias Schnelte (1): bitbake: fetch2: Adds vscode devcontainer support Michael Opdenacker (18): base: add newline before LICENSE_FLAGS_DETAILS dev-manual: new-recipe.rst fix inconsistency with contributor guide contributor-guide: recipe-style-guide: add Upstream-Status dev-manual: licenses: update license manifest location dev-manual: licenses: mention SPDX for license compliance dev-manual: disk-space: improve wording for obsolete sstate cache files sdk-manual: extensible.rst: fix multiple formatting issues alsa-lib: upgrade 1.2.9 -> 1.2.10 alsa-utils: upgrade 1.2.9 -> 1.2.10 shadow: fix patch Upstream-Status libevent: fix patch Upstream-Status alsa-utils: update patch Upstream-Status alsa-lib: fix patch Upstream-Status lib/oe/qa: remove obsolete "Accepted" string for Upstream-Status lib/oe/qa: update guidelines link for Upstream-Status bsp-guide: bsp.rst: replace reference to wiki dev-manual: new-recipe.rst: replace reference to wiki maintainers.inc: add self for flac recipe Mikko Rapeli (9): openssh: update Upstream-Status to Denied in test logging patch openssh: improve banner ptest failure logging testimage.bbclass: detect slirp from TEST_RUNQEMUPARAMS oeqa dnf_runtime.py: fix HTTP server IP address and port oeqa selftest runtime_test.py: append to TEST_RUNQEMUPARAMS selftest runtime_test.py: add testimage.bbclass slirp test openssh: capture logs in run-ptest testimage.bbclass: remove QEMU_USE_SLIRP variable oeqa/selftest/context.py: check git command return values Ninad Palsule (1): kernel-fitImage: Strip path component from dtb Peter Kjellerstedt (7): libsoup-2.4: Only specify --cross-file when building for target libsoup: Only specify --cross-file when building for target bitbake: tinfoil: Do not fail when logging is disabled and full config is used bitbake: bitbake-getvar: Make --quiet work with --recipe bitbake: bitbake-getvar: Make --value imply --quiet bitbake: bitbake-getvar: Add a (suppressable) error for undefined variables bitbake: bitbake-getvar: Treat undefined variables as empty with --value Peter Marko (2): openssl: Upgrade 3.1.2 -> 3.1.3 json-c: define CVE_VERSION Qiu Tingting (1): tar: add ptest support Richard Purdie (34): bitbake.conf: Add IMAGE_BASENAME to SDK_NAME vim: Upgrade 9.0.1664 -> 9.0.1894 defaultsetup: Inherit create-spdx by default oeqa/selftest/runtime_test: No need to use append with TEST_RUNQEMUPARAMS devtool/build_sdk: Drop unused imports bitbake: lib: Drop inotify support and replace with mtime checks bitbake: server/process: Disable the flush() call in server logging recipetool/devtool: Ensure server knows about changed files lttng-tools: Upgrade 2.13.10 -> 2.13.11 oeqa/selftest/wic: Improve assertTrue calls elfutils: Fix reproducibility issue with bunzip2 bitbake: cooker: Drop unneeded flush calls sstate: Fix nativesdk entry in SSTATE_ARCHS multilib: fix SSTATE_ARCHS for multilib usage license/license_image: Fix license file layout to avoid overlapping files oeqa/selftest/bbtests: Improve and update test_non_gplv3 create-spdx/sbom: Ensure files don't overlap between machines sstate: Stop allowing overlapping symlinks from sstate recipes: Drop remaining PR values from recipes bitbake.conf: No longer support PR from filename oeqa/selftest: Fix broken symlink removal handling oeqa/selftest/reproducible: Avoid oe-selftest startup delays oeqa: Streamline oe-selftest startup time oeqa/selftest/oescripts: Avoid variable access at module load bitbake: codeparser: Update debug variable reference contributor-guide/style-guide: Refer to recipes, not packages contributor-guide/style-guide: Add a note about task idempotence lib: Import packagedata oe module by default oeqa/runner: Ensure class setup errors are shown to bitbake logging create-spdx: Ensure it is clear where the message comes from oeqa/utils/gitarchive: Handle broken commit counts in results repo python3-numpy: Fix reproducibility issue scritps/runqemu: Ensure we only have two serial ports glibc: Pull in stable branch fixes Robert Joslyn (2): curl: Update from 8.2.1 to 8.3.0 curl: Skip tests marked flaky Robert Yang (1): libxcrypt-compat: Remove libcrypt.so to fix conflict with libcrypt Roland Hieber (7): template: fix typo in section header ref-manual: point outdated link to the new location contributor-guide: recipe-style-guide: add more patch tagging examples contributor-guide: recipe-style-guide: add section about CVE patches contributor-guide: discourage marking patches as Inappropriate contributor-guide: deprecate "Accepted" patch status contributor-guide: style-guide: discourage using Pending patch status Ross Burton (19): packagegroup-core-x11-xserver: add modesetting driver to default XSERVER machine/qemu*: add modesetting drivers to XSERVER beaglebone-yocto: remove redundant XSERVER assignment gcc: Fix -fstack-protector issue on aarch64 testimage: respect target/server IPs when using slirp manuals: document LICENSE_FLAGS_DETAILS linux-yocto: update CVE ignores libwebp: upgrade to 1.3.2 oeqa/runtime/parselogs: remove unused imports oeqa/runtime/parselogs: don't bother to show target hardware information oeqa/runtime/parselogs: remove obsolete LSB testing support oeqa/runtime/parselogs: inline single-caller functions oeqa/runtime/parselogs: improve find call oeqa/runtime/parselogs: don't pass around members oeqa/runtime/parselogs: move some variables out of global scope oeqa/runtime/parselogs: select the correct machine-specific ignores early oeqa/runtime/parselogs: parse the logs with Python, not grep webkitgtk: reduce size of -dbg package bitbake: bitbake/lib: spawn server/worker using the current Python interpreter Samantha Jalabert (14): python3-isodate: Copy recipe from meta-python python3-booleanpy: Copy recipe from meta-python python3-beartype: add recipe python3-click: Copy recipe from meta-python ptest-packagelists.inc: add python test click python3-license-expression: Copy recipe from meta-python ptest-packagelists.inc: add python test license-expression python3-rdflib: Copy recipe from meta-python python3-uritools: add recipe python3-xmltodict: Copy recipe from meta-python ptest-packagelists.inc: add python test xmltodict python3-spdx-tools: add recipe qa: Add selftest for python3-spdx-tools maintainers.inc: add python3-spdx-tools and dependencies Sean Nyekjaer (1): gcc: depend on zstd Stefan Tauner (1): gdb: fix RDEPENDS for PACKAGECONFIG[tui] Stephan Wurm (1): python3-jsonschema: Update homepage URL Tim Orling (1): python3-cryptography{-vectors}: upgrade to 41.0.4 Trevor Gamblin (6): patchtest: Add tests from patchtest oe repo patchtest/selftest: remove configurable target patchtest: add requirements.txt patchtest: Add README.md for selftests python3-ptest: skip test_input_no_stdout_fileno patchtest/selftest: only split resultlines once Ulrich Ölmann (1): packagegroup-base: clean up setting packagegroup-machine-base's SUMMARY Wang Mingyu (36): alsa-ucm-conf: upgrade 1.2.9 -> 1.2.10 at-spi2-core: upgrade 2.48.3 -> 2.48.4 dbus: upgrade 1.14.8 -> 1.14.10 debianutils: upgrade 5.8 -> 5.12 dnf: upgrade 4.16.1 -> 4.17.0 harfbuzz: upgrade 8.1.1 -> 8.2.0 kexec-tools: upgrade 2.0.26 -> 2.0.27 libinput: upgrade 1.23.0 -> 1.24.0 libnl: upgrade 3.7.0 -> 3.8.0 nghttp2: upgrade 1.55.1 -> 1.56.0 ccache: upgrade 4.8.2 -> 4.8.3 pkgconf: upgrade 2.0.2 -> 2.0.3 python3-git: upgrade 3.1.34 -> 3.1.35 python3-hypothesis: upgrade 6.84.0 -> 6.84.3 python3-pyelftools: upgrade 0.29 -> 0.30 python3-pytest: upgrade 7.4.1 -> 7.4.2 python3-setuptools: upgrade 68.1.2 -> 68.2.1 strace: upgrade 6.4 -> 6.5 stress-ng: upgrade 0.16.04 -> 0.16.05 wayland-utils: upgrade 1.1.0 -> 1.2.0 wireless-regdb: upgrade 2023.05.03 -> 2023.09.01 at-spi2-core: upgrade 2.48.4 -> 2.50.0 enchant2: upgrade 2.5.0 -> 2.6.1 harfbuzz: upgrade 8.2.0 -> 8.2.1 kbd: upgrade 2.6.2 -> 2.6.3 libsecret: upgrade 0.21.0 -> 0.21.1 gobject-introspection: upgrade 1.78.0 -> 1.78.1 python3-numpy: upgrade 1.25.2 -> 1.26.0 python3-hypothesis: upgrade 6.84.3 -> 6.86.2 python3-pycryptodome: upgrade 3.18.0 -> 3.19.0 python3-pycryptodomex: upgrade 3.18.0 -> 3.19.0 python3-smmap: upgrade 5.0.0 -> 6.0.0 python3-trove-classifiers: upgrade 2023.8.7 -> 2023.9.19 python3-typing-extensions: upgrade 4.7.1 -> 4.8.0 python3-urllib3: upgrade 2.0.4 -> 2.0.5 python3-zipp: upgrade 3.16.2 -> 3.17.0 Yash Shinde (1): glibc: fix CVE-2023-4527 Yogita Urade (2): tiff: fix CVE-2023-40745 tiff: fix CVE-2023-41175 meta-openembedded: eff1b182c1..ea42cec2ec: Alex Kiernan (2): mdns: Upgrade 1790.80.10 -> 2200.0.8 jq: Upgrade 1.6+git -> 1.7 Archana Polampalli (2): python3-appdirs: print ptest results in unified format nodejs: upgrade 18.17.1 -> 20.5.1 Armin Kuster (1): openldap: update to 2.5.16. Bruce Ashfield (2): zfs: update to v2.2.0-rc4 vboxguestdrivers: fix kernel v6.5 build Chi Xu (1): mariadb: Add ptest support Clément Péron (6): etcd-cpp-apiv3: upgrade 0.14.3 -> 0.15.3 devtools: grpc: bump to 1.56.2 protobuf: upgrade 4.22.2 -> 4.23.4 protobuf-c: bump to next release to support protobuf 4.23.x mariadb: add missing in rocksdb string_util.h etcd-cpp-apiv3: fix build when gRPC is cross compiled Daniel Semkowicz (2): cockpit: Move packagekit to a separate package cockpit: Move apps to a separate package Derek Straka (54): python3-absl: Update version 1.4.0 -> 2.0.0 python3-brotli: Update version 1.0.9 -> 1.1.0 python3-cachecontrol: Update version 0.13.0 -> 0.13.1 python3-cantools: Update version 38.0.2 -> 39.2.0 python3-cerberus: Update version 1.3.4 -> 1.3.5 python3-configshell-fb: Update version 1.1.29 -> 1.1.30 python3-custom-inherit: Update version 2.3.1 -> 2.4.1 python3-distlib: Update version 0.3.6 -> 0.3.7 python3-fasteners: Update version 0.18 -> 0.19 python3-filelock: Update version 3.12.0 -> 3.12.4 python3-bleak: Update version 0.20.2 -> 0.21.1 python3-dynamic-dispatch: Correct the upstream regex check for version upgrades python3-google-api-python-client: Update version 2.99.0 -> 2.100.0 python3-sqlalchemy: Upgrade 2.0.20 -> 2.0.21 python3-netaddr: Update version 0.8.0 -> 0.9.0 python3-msgpack: Update version 1.0.5 -> 1.0.6 python3-protobuf: Update version 4.24.2 -> 4.24.3 python3-gevent: Update version 23.7.0 -> 23.9.1 python3-langtable: Update version 0.0.63 -> 0.0.64 python3-posix-ipc: Update version 1.0.5 -> 1.1.1 python3-websocket-client: Update version 1.5.3 -> 1.6.3 python3-web3: Update version 6.9.0 -> 6.10.0 python3-apiflask: Update version 2.0.1 -> 2.0.2 python3-argh: Update version 0.29.3 -> 0.29.4 python3-async-timeout: remove old version of the library python3-pydantic: Update version 1.10.7 -> 2.4.1 python3-pyhamcrest: Fix upstream check by specifying the UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX python3-pyasn1-modules: Update version 0.2.8 -> 0.3.0 python-pyiface: Update version from git -> 0.0.11 python3-pymysql: Fix upstream check by specifying the UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX python3-pymysql: update verion 1.0.2 -> 1.1.0 python3-pyproj: update version 3.6.0 -> 3.6.1 python3-pyproject-api: update version 1.5.1 -> 1.6.1 python3-redis: update version 5.0.0 -> 5.0.1 python3-traitlets: update version 5.9.0 -> 5.10.1 python3-xxhash: update version 3.2.0 -> 3.3.0 python3-pyzmq: update version 25.0.0 -> 25.1.1 python3-cachecontrol: Fix upstream check by specifying the UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX python3-flask-babel: update version 2.0.0 -> 3.1.0 python3-idna-ssl: Fix upstream check by specifying the UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX python3-ninja-syntax: Fix upstream check by specifying the UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX python3-prettytable: update version 3.6.0 -> 3.9.0 python3-pytz-deprecation-shim: Remove outdated recipe meant to be a short lived shim python3-tzlocal: Remove dependency on pytz_deprecation_shim removed in release 5.0 python3-astroid: update version 2.16.6 -> 3.0.0 python3-flask: update version 2.3.2 -> 2.3.3 python3-google-api-core: update version 2.12.0 python3-google-api-python-client: update version 2.100.0 -> 2.101.0 python3-google-auth: update version 2.23.0 -> 2.23.1 python3-parse-type: update version 0.5.2 -> 0.6.2 python3-nacl: Add recipe for the latest release of PyNaCl python3-botocore: add recipe for latest version of botocore python3-boto3: add recipe for latest version of boto3 python3-flask-cors: add initial version of the recipe for 4.0.0 Etienne Cordonnier (1): uutils-coreutils: upgrade 0.0.20 -> 0.0.21 Gianfranco Costamagna (3): mosquitto: do not automatically depend on dlt-daemon, it's a non-mandatory logging system mosquitto: upgrade 2.0.15 -> 2.0.17 mosquitto: upgrade 2.0.17 -> 2.0.18 Jeffrey Pautler (1): bolt: disable CVE checking for this recipe Jonas Gorski (1): frr: upgrade 8.4.4 -> 9.0.1 Julian Haller (1): openct: Fix typo in SUMMARY variable Kai Kang (1): ostree: not compatible with riscv32 when ptest enabled Khem Raj (25): vlc: Fix build with gettext 0.22+ usbguard: Enable seccomp if distro features have it sharutils: Check for intmax_t using configure poco: Add pass/fail ststus into logs mongodb: Add rdep on tzdata-core mongodb: Upgrade to 4.4.24 meta-oe-ptest-image-poco: Increase size tp 1G poco: Fix ptest runtime errors poco: Do not enable MongoDB packageconfig by default plocate: Upgrade to 1.1.19 release xscreensaver: Add osuosl backup MIRROR mozjs-115: Apply autoconf tuple mismatch fix cpp-netlib: Fix build with boost 1.80+ cpp-netlib: Fix buildpaths in generated cmake files python3-pybluez: Fix patch upstream-status python3-pynetlinux: Fix patch upstream-status libnet-idn-encode: Add recipe libio-socket-ssl-perl: Change libnet-libidn-perl->libnet-idn-encode rdep for ptests libnfs: Drop -Wno-implicit-function-declaration webkitgtk3: Do not use musttail with clang on arm fftw: Fix ptest result reporting nodejs: Fix ptest result reporting relayd: Update to latest tip of trunk relayd: Fix build with clang kernel-selftest: Build headers before compiling tests Lee Chee Yang (8): libsdl: fix CVE-2022-34568 keepalived: 2.2.2 -> 2.2.8 irssi: 1.4.2 -> 1.4.4 iniparser: Fix CVE-2023-33461 opensc: fix CVE-2023-2977 x11vnc: Fix CVE-2020-29074 libvncserver: update to 0.9.14 ntpsec: 1.2.2 -> 1.2.2a Markus Volk (48): libei: add recipe libxmlb: update 0.3.10 -> 0.3.14 appstream: update 0.16.2 -> 0.16.3 webrtc-audio-processing: add recipe for 1.x pipewire: upgrade 0.3.79 -> 0.3.80 evolution-data-server: upgrade 3.48.3 -> 3.50.0 appstream: remove workaround for cross-compile libxmlb: fix a reproducibility and runtime issue with ptest tracker-miners: upgrade 3.5.0 -> 3.6.0 mozjs: upgrade 102.9.0 -> 102.15.0 tecla: add recipe polkit: upgrade 122 -> 123 tracker: upgrade 3.5.1 -> 3.6.0 libxmlb: remove recipe appstream: remove recipe gvfs: upgrade 1.51.90 -> 1.52.0 mutter: upgrade 44.3 -> 45.0 xdg-desktop-portal: upgrade 1.16.0 -> 1.18.0 gnome-boxes: upgrade 44.2 -> 45.0 gnome-session: upgrade 44.0 -> 45.0 gnome-text-editor: upgrade 44.0 -> 45.0 gnome-shell: upgrade 44.3 -> 45.0 eog: upgrade 44.3 -> 45.0 gnome-calculator: upgrade 44.0 -> 45.0 xdg-desktop-portal-gnome: upgrade 44.1 -> 45.0 gnome-calendar: upgrade 44.0 -> 45.0 gnome-software: upgrade 44.4 -> 45.0 zenity: upgrade 3.44.0 -> 3.44.2 gnome-system-monitor: upgrade 44.0 -> 45.0 webkitgtk: upgrade 2.40.5 -> 2.42.0 gnome-control-center: upgrade 44.3 -> 45.0 gnome-settings-daemon: upgrade 44.1 -> 45.0 tracker: add missing Upstream-Status gdm: upgrade 44.1 -> 45.0.1 gnome-calendar: fix reproducibility issue exiv2: Upgrade 0.27.6 -> 0.28.0 gexiv: Upgrade 0.14.0 -> 0.14.2 gjs: Upgrade 1.76.1 -> 1.78.0 mozjs: add recipe for v115 evince: Upgrade 44.2 -> 45.0 Nautilus: Upgrade 44.2.1 -> 45.0 gedit: Upgrade 44.2 -> 46.1 tepl: Upgrade 6.4.0 -> 6.8.0 libblockdev: Upgrade 2.28 -> 3.03 udisks2: Upgrade 2.9.4 -> 2.10.1 mozjs: Upgrade 102.15.0 -> 102.15.1 libnfs: dont install libnfs-config.cmake gnome-remote-desktop: Upgrade 44.2 -> 45.0 Martin Jansa (20): webrtc-audio-processing: Fix build with -Werror=return-type freeglut: return x11 to REQUIRED_DISTRO_FEATURES packagegroup-meta-multimedia: restore x11 restriction for projucer btrfsmaintenance: move btrfs-tools dependency from build-time to run-time btrfsmaintenance: drop allarch ttf-google-fira: exclude siggen dependency on fontconfig cukinia: drop allarch mdio-tools: exclude siggen dependency on mdio-netlink ot-br-posix: exclude siggen dependency on ipset mongodb: add and fix Upstream-Status mongodb: Fix build on 32bit gupnp: fix build with meson-1.2.0 minifi-cpp, mozjs-115, redis-7.2.1, pv: add missing Upstream-Status mozjs: fix filename in MULTILIB_SCRIPTS gupnp-tools: fix build with meson-1.2.0 gnome-tweaks, networkmanager-fortisslvpn, libesmtp, json-schema-validator, python3-pybluez, python3-pynetlinux, apache2: Fix Malformed Upstream-Status mozjs: use PV in MULTILIB_SCRIPTS mosquitto, etcd-cpp-apiv3: add missing Upstream-Status meta-oe/dynamic-layers: add Upstream-Status where missing meta-oe/dynamic-layers: add one more missing Upstream-Status and fix one malformed Michał Iwanicki (1): python3-pyu2f: add recipe Mingli Yu (4): minifi-cpp: Remove the buildpath issue hdf5: Upgrade to 1.14.2 vlock: Use EXTRA_CFLAGS mozjs-102: Remove the buildpath Richard Leitner (2): python3-shellingham: add recipe for v1.5.3 python3-autoflake: add recipe for v2.2.1 Ross Burton (1): webkitgtk3: reduce size of -dbg package Sam Van Den Berge (6): python3-flask-jwt-extended: add recipe python3-flask-marshmallow: add recipe python3-apispec: add recipe python3-flask-httpauth: add recipe python3-webargs: add recipe python3-apiflask: add recipe Samantha Jalabert (6): Remove python3-rdflib Remove python3-license-expression Remove python3-xmltodict Remove python3-booleanpy Remove python3-click Remove python3-isodate Samuli Piippo (1): protobuf: stage protoc binary to sysroot Sanjay Chitroda (1): netkit-telnet: Fix CVE-2022-39028 Trevor Gamblin (1): python3-aiofiles: upgrade 23.1.0 -> 23.2.1 Vyacheslav Yurkov (3): overlayfs-tools: Drop unneeded dependency overlayfs-tools: Bump up the version overlayfs-tools: Install fsck binary Wang Mingyu (42): freerdp: upgrade 2.10.0 -> 2.11.0 boost-sml: upgrade 1.1.8 -> 1.1.9 ctags: upgrade 6.0.20230827.0 -> 6.0.20230917.0 dovecot: upgrade 2.3.20 -> 2.3.21 freerdp: upgrade 2.11.0 -> 2.11.1 gensio: upgrade 2.7.5 -> 2.7.6 geoclue: upgrade 2.7.0 -> 2.7.1 hwloc: upgrade 2.9.2 -> 2.9.3 iperf3: upgrade 3.14 -> 3.15 libcloudproviders: upgrade 0.3.2 -> 0.3.4 libdeflate: upgrade 1.18 -> 1.19 libglvnd: upgrade 1.6.0 -> 1.7.0 libtommath: upgrade 1.2.0 -> 1.2.1 libcoap: upgrade 4.3.1 -> 4.3.3 python3-antlr4-runtime: upgrade 4.13.0 -> 4.13.1 python3-lazy: upgrade 1.5 -> 1.6 python3-pyfanotify: upgrade 0.2.0 -> 0.2.1 psqlodbc: upgrade 15.00.0000 -> 16.00.0000 python3-argcomplete: upgrade 3.1.1 -> 3.1.2 python3-bitstring: upgrade 4.1.1 -> 4.1.2 python3-cmake: upgrade 3.27.4.1 -> 3.27.5 python3-coverage: upgrade 7.3.0 -> 7.3.1 python3-engineio: upgrade 4.7.0 -> 4.7.1 python3-eth-utils: upgrade 2.2.0 -> 2.2.1 python3-flask-migrate: upgrade 4.0.4 -> 4.0.5 python3-flask-socketio: upgrade 5.3.5 -> 5.3.6 python3-google-api-python-client: upgrade 2.97.0 -> 2.99.0 python3-google-auth: upgrade 2.22.0 -> 2.23.0 python3-pillow: upgrade 10.0.0 -> 10.0.1 python3-pymisp: upgrade 2.4.175 -> 2.4.176 python3-pymodbus: upgrade 3.5.0 -> 3.5.2 python3-rapidjson: upgrade 1.10 -> 1.11 python3-rich: upgrade 13.5.2 -> 13.5.3 python3-term: upgrade 2.4 -> 2.5 python3-tox: upgrade 4.11.1 -> 4.11.3 python3-typeguard: upgrade 4.1.3 -> 4.1.5 python3-types-setuptools: upgrade 68.1.0.1 -> 68.2.0.0 python3-virtualenv: upgrade 20.24.4 -> 20.24.5 python3-xlsxwriter: upgrade 3.1.2 -> 3.1.3 python3-zeroconf: upgrade 0.97.0 -> 0.112.0 redis: upgrade 7.2.0 -> 7.2.1 remmina: upgrade 1.4.31 -> 1.4.32 Xiangyu Chen (3): mosh: add support of protobuf 4.22.x protobuf: upgrade 3.21.12 -> 4.22.2 protobuf-c: add support of protobuf 4.22.x Yi Zhao (1): audit: upgrade 3.1.1 -> 3.1.2 meta-arm: bd0953cc60..95789365f7: Abdellatif El Khlifi (2): arm-bsp/trusted-firmware-a: corstone1000: enable ERRATA_A35_855472 arm-bsp/u-boot: corstone1000: purge U-Boot specific DT nodes before Linux Adam Johnston (1): arm-bsp/trusted-firmware-a: Fix BL32 path if usrmerge enabled Divin Raj (1): ci,doc,kas,arm-bsp,arm: Remove support for fvp-baser-aemv8r64 machine Emekcan Aras (6): arm-bsp/optee-os: corstone1000: Handling logging syscall correctly CI: Add meta-secure-core CI: Include meta-secure-core in corstone1000 kas: corstone1000: add meta-secure-core arm-bsp/u-boot: corstone1000: introduce authenticated capsule update arm-bsp/trusted-firmware-m: Enable authenticated capsule update Javier Tia (2): optee-client: start tee-supplicant.service when teeprivX dev is detected libts: tee-udev.rules: Change ownership to tee group Jon Mason (5): arm/edk2: update to edk2-stable202308 arm/trusted-firmware-m: update to 1.8.1 arm/opencsd: update to v1.4.1 arm/scp-firmware: update to v2.13.0 README: remove reference to meta-arm-autonomy Khem Raj (1): layer.conf: update LAYERSERIES_COMPAT for nanbield Mariam Elshakfy (2): arm-bsp/optee-os: N1SDP upgrade optee-os to 3.22 arm-bsp/optee-os: N1SDP upgrade tadevkit and optee-test to 3.22 Peter Hoyes (2): CI: Allow a GitHub container registry mirror to be specified CI: Make update-repos more resilient to network issues Ross Burton (15): arm/generic-arm64: move SERIAL_CONSOLES to generic-arm64 arm/qemu-generic-arm64: force off KVM in qemu arm/generic-arm64: set XSERVER to install the modesetting driver CI: remove redundant variables in testimage.yml arm-bsp: change port mapping for SSH to port 2222 arm/apply_local_src_patches: allow use in multiple directories arm/trusted-services: pass through CMake generator arm/trusted-services: add missing pkgconfig inherit arm/trusted-services/ts-remote-test: move binary to $bindir arm/trusted-services/ts-sp-env-test: add missing DEPENDS arm/trusted-services/ts-sp-env-test: remove arm/trusted-services: use apply_local_src_patches arm/trusted-services: upgrade nanopb and fix build races CI: use a venv for sphinx CI: upgrade to Kas 4 container Xueliang Zhong (2): arm-bsp/n1sdp: update to linux yocto kernel 6.4 arm-bsp/corstone1000: bump kernel version to v6.4 meta-security: 1856a7cf43..aca6d4a9e7: Armin Kuster (10): suricata: fix build issue. suricata: Update to 7.0.0 sssd: Update to 2.9.2 openscap: update to 1.3.9 python3-privacyidea: update to 3.8.1 lkrg-module: update to 0.9.7 libhtp: update to 0.5.45 swtpm: update 0.8.1 lynis: Update to 3.0.9 scap-security-guide: Drop Poky patch and update to tip John Broadbent (1): libhoth: Update meta-raspberrypi: 6501ec892c..482d864b8f: Joshua Watt (1): rpi-base: Fix wic image kernel dependency Khem Raj (5): userland: Update to trunk from 20230419 linux-raspberrypi: Upgrade 6.1 release to latest point release 6.1.54 linux-firmware-rpidistro: Update to 20230210-5_bpo11+1 bluez-firmware-rpidistro: Update to 1.2-4+rpt10 raspberrypi-firmware: Update to 20230509~buster Martin Jansa (1): layer.conf: update LAYERSERIES_COMPAT for nanbield Change-Id: Id75112a3b0be4bd150dc5d9a28c01982ed48200e Signed-off-by: Andrew Geissler --- meta-arm/meta-arm-bsp/conf/layer.conf | 2 +- .../conf/machine/corstone1000-fvp.conf | 2 +- .../conf/machine/fvp-baser-aemv8r64.conf | 66 - .../machine/include/arm/armv8r/arch-armv8r64.inc | 10 - .../conf/machine/include/corstone1000.inc | 2 +- .../conf/machine/include/fvp-common.inc | 6 +- meta-arm/meta-arm-bsp/conf/machine/n1sdp.conf | 4 +- meta-arm/meta-arm-bsp/conf/machine/tc1.conf | 2 +- .../documentation/fvp-baser-aemv8r64.md | 264 - .../boot-wrapper-aarch64-fvp-baser-aemv8r64.inc | 36 - .../boot-wrapper-aarch64_%.bbappend | 4 - ...ame-labels-and-prepare-for-lower-EL-booti.patch | 135 - .../0002-aarch64-Prepare-for-EL1-booting.patch | 48 - ...0003-aarch64-Prepare-for-lower-EL-booting.patch | 55 - .../0004-gic-v3-Prepare-for-gicv3-with-EL2.patch | 105 - ...0005-aarch64-Prepare-for-booting-with-EL2.patch | 63 - ...troduce-EL2-boot-code-for-Armv8-R-AArch64.patch | 182 - ...enable-psci-to-choose-between-smc-and-hvc.patch | 89 - ...arch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch | 48 - .../0009-lds-Mark-the-mem-range.patch | 38 - .../0010-common-Introduce-the-libfdt.patch | 6044 -------------------- .../0011-common-Add-essential-libc-functions.patch | 101 - ...ile-Add-the-libfdt-to-the-Makefile-system.patch | 61 - .../0013-platform-Add-print_hex-func.patch | 67 - .../0014-common-Add-mem-usage-to-memreserve.patch | 96 - ...oot-Add-the-enable-keep-el-compile-option.patch | 102 - ...6-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch | 31 - ...ply-flush-cache-after-setting-branch_data.patch | 49 - .../0018-PSCI-Add-function-call-entry-point.patch | 71 - .../0019-lds-Rearrange-and-mark-the-sections.patch | 58 - ...common-Provide-firmware-info-using-libfdt.patch | 342 -- ...-boot-Enable-firmware-node-initialization.patch | 95 - .../trusted-firmware-a-corstone1000.inc | 3 +- .../trusted-firmware-a-n1sdp.inc | 2 +- .../trusted-firmware-a/trusted-firmware-a-tc.inc | 2 +- ...atform-Corstone1000-Enable-Signed-Capsule.patch | 102 + .../trusted-firmware-m-corstone1000.inc | 1 + ...a-way-to-remove-non-compliant-nodes-and-p.patch | 137 + ...otefi-Call-the-EVT_FT_FIXUP-event-handler.patch | 56 + ...rstone1000-purge-U-Boot-specific-DT-nodes.patch | 51 + ...one1000-add-signature-device-tree-overlay.patch | 31 + ...e1000-enable-authenticated-capsule-config.patch | 28 + ...0-introduce-EFI-authenticated-capsule-upd.patch | 76 + ...1-armv8-Add-ARMv8-MPU-configuration-logic.patch | 257 - ...ss64-add-MPU-memory-map-for-the-BASER_FVP.patch | 59 - ...-disabling-exception-vectors-on-non-SPL-b.patch | 104 - ...04-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch | 140 - ...disabling-HVC-configurable-when-switching.patch | 80 - ...6-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch | 30 - ...Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch | 25 - ...low-PRBAR-MPU-attributes-to-be-configured.patch | 103 - ...e-icache-when-switching-exception-levels-.patch | 61 - .../recipes-bsp/u-boot/u-boot_%.bbappend | 35 +- .../recipes-bsp/uefi/edk2-firmware_202305.bb | 7 + .../fvp-baser-aemv8r64-preempt-rt.scc | 6 - .../arm-platforms/fvp-baser-aemv8r64-standard.scc | 7 - .../bsp/arm-platforms/fvp-baser-aemv8r64.scc | 4 - .../0002-Add-external-system-driver.patch | 17 +- .../0003-Add-rpmsg-driver-for-corstone1000.patch | 7 +- .../0004-rpmsg-arm-fix-return-value.patch | 7 +- ...arm-update-chrdev-to-ctrldev-registration.patch | 7 +- ...006-Adds-workaround-for-cs1k-specific-bug.patch | 11 +- .../fvp-baser-aemv8r64/fvp-baser-aemv8r64.dts | 212 - .../recipes-kernel/linux/linux-arm-platforms.inc | 10 +- ...mmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch | 47 - ...ci_quirk-add-acs-override-for-PCI-devices.patch | 159 - ...quirk-for-the-Arm-Neoverse-N1SDP-platform.patch | 324 -- ...add-quirk-support-enabling-remote-chip-PC.patch | 136 - ...Whitelist-early-Arm-Neoverse-N1-revisions.patch | 33 - ...nfig-disable-config-options-that-does-not.patch | 39 - .../linux/linux-yocto-6.1/n1sdp/enable-nvme.cfg | 3 - .../linux-yocto-6.1/n1sdp/enable-realtek-R8169.cfg | 3 - .../linux-yocto-6.1/n1sdp/enable-usb_conn_gpio.cfg | 2 - .../linux-yocto-6.1/n1sdp/usb_xhci_pci_renesas.cfg | 2 - ...mmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch | 47 + ...ci_quirk-add-acs-override-for-PCI-devices.patch | 159 + ...quirk-for-the-Arm-Neoverse-N1SDP-platform.patch | 324 ++ ...add-quirk-support-enabling-remote-chip-PC.patch | 136 + ...Whitelist-early-Arm-Neoverse-N1-revisions.patch | 33 + ...nfig-disable-config-options-that-does-not.patch | 50 + .../linux/linux-yocto-6.4/n1sdp/enable-nvme.cfg | 3 + .../linux-yocto-6.4/n1sdp/enable-realtek-R8169.cfg | 3 + .../linux-yocto-6.4/n1sdp/enable-usb_conn_gpio.cfg | 2 + .../linux-yocto-6.4/n1sdp/usb_xhci_pci_renesas.cfg | 2 + .../recipes-kernel/linux/linux-yocto-rt_%.bbappend | 1 - .../corstone1000/0001-Handle-logging-syscall.patch | 32 + ...002-plat-n1sdp-add-N1SDP-platform-support.patch | 28 +- .../n1sdp/0004-Handle-logging-syscall.patch | 6 +- .../optee/optee-client/tee-supplicant.service | 11 - .../optee/optee-client/tee-supplicant@.service | 10 + .../optee/optee-os-corstone1000-common.inc | 5 + .../optee/optee-os-tadevkit_3.20.0.bbappend | 6 - .../optee/optee-os-tadevkit_3.22.0.bbappend | 6 + .../optee/optee-os_3.20.0.bbappend | 1 - .../optee/optee-os_3.22.0.bbappend | 1 + .../optee/optee-test_3.18.0.bbappend | 6 - .../optee/optee-test_3.22.0.bbappend | 6 + .../trusted-services/ts-arm-platforms.inc | 16 +- 98 files changed, 1377 insertions(+), 10221 deletions(-) delete mode 100644 meta-arm/meta-arm-bsp/conf/machine/fvp-baser-aemv8r64.conf delete mode 100644 meta-arm/meta-arm-bsp/conf/machine/include/arm/armv8r/arch-armv8r64.inc delete mode 100644 meta-arm/meta-arm-bsp/documentation/fvp-baser-aemv8r64.md delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64-fvp-baser-aemv8r64.inc delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64_%.bbappend delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0001-aarch64-Rename-labels-and-prepare-for-lower-EL-booti.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0002-aarch64-Prepare-for-EL1-booting.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0003-aarch64-Prepare-for-lower-EL-booting.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0004-gic-v3-Prepare-for-gicv3-with-EL2.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0005-aarch64-Prepare-for-booting-with-EL2.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0006-aarch64-Introduce-EL2-boot-code-for-Armv8-R-AArch64.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0007-Allow-enable-psci-to-choose-between-smc-and-hvc.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0008-aarch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0009-lds-Mark-the-mem-range.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0010-common-Introduce-the-libfdt.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0011-common-Add-essential-libc-functions.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0012-Makefile-Add-the-libfdt-to-the-Makefile-system.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0013-platform-Add-print_hex-func.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0014-common-Add-mem-usage-to-memreserve.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0015-boot-Add-the-enable-keep-el-compile-option.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0016-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0017-PSCI-Apply-flush-cache-after-setting-branch_data.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0018-PSCI-Add-function-call-entry-point.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0019-lds-Rearrange-and-mark-the-sections.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0020-common-Provide-firmware-info-using-libfdt.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0021-boot-Enable-firmware-node-initialization.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Enable-Signed-Capsule.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0035-dt-Provide-a-way-to-remove-non-compliant-nodes-and-p.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0036-bootefi-Call-the-EVT_FT_FIXUP-event-handler.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0037-corstone1000-purge-U-Boot-specific-DT-nodes.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0038-corstone1000-add-signature-device-tree-overlay.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0039-corstone1000-enable-authenticated-capsule-config.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0040-corstone1000-introduce-EFI-authenticated-capsule-upd.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0001-armv8-Add-ARMv8-MPU-configuration-logic.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0005-armv8-Make-disabling-HVC-configurable-when-switching.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Enable-icache-when-switching-exception-levels-.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-bsp/uefi/edk2-firmware_202305.bb delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-preempt-rt.scc delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-standard.scc delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64.scc delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/files/fvp-baser-aemv8r64/fvp-baser-aemv8r64.dts delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-nvme.cfg delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-realtek-R8169.cfg delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-usb_conn_gpio.cfg delete mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/usb_xhci_pci_renesas.cfg create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-nvme.cfg create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-realtek-R8169.cfg create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-usb_conn_gpio.cfg create mode 100644 meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/usb_xhci_pci_renesas.cfg create mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/corstone1000/0001-Handle-logging-syscall.patch delete mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant.service create mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant@.service delete mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.20.0.bbappend create mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.22.0.bbappend delete mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.18.0.bbappend create mode 100644 meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.22.0.bbappend (limited to 'meta-arm/meta-arm-bsp') diff --git a/meta-arm/meta-arm-bsp/conf/layer.conf b/meta-arm/meta-arm-bsp/conf/layer.conf index e192a83ddf..97d9728c87 100644 --- a/meta-arm/meta-arm-bsp/conf/layer.conf +++ b/meta-arm/meta-arm-bsp/conf/layer.conf @@ -9,7 +9,7 @@ BBFILE_COLLECTIONS += "meta-arm-bsp" BBFILE_PATTERN_meta-arm-bsp = "^${LAYERDIR}/" BBFILE_PRIORITY_meta-arm-bsp = "5" -LAYERSERIES_COMPAT_meta-arm-bsp = "mickledore" +LAYERSERIES_COMPAT_meta-arm-bsp = "nanbield" LAYERDEPENDS_meta-arm-bsp = "core meta-arm" # This won't be used by layerindex-fetch, but works everywhere else diff --git a/meta-arm/meta-arm-bsp/conf/machine/corstone1000-fvp.conf b/meta-arm/meta-arm-bsp/conf/machine/corstone1000-fvp.conf index ebfba5b93f..5b3e150260 100644 --- a/meta-arm/meta-arm-bsp/conf/machine/corstone1000-fvp.conf +++ b/meta-arm/meta-arm-bsp/conf/machine/corstone1000-fvp.conf @@ -24,7 +24,7 @@ FVP_CONFIG[se.BootROM_config] ?= "3" FVP_CONFIG[board.hostbridge.interfaceName] ?= "tap0" FVP_CONFIG[board.smsc_91c111.enabled] ?= "1" FVP_CONFIG[board.hostbridge.userNetworking] ?= "true" -FVP_CONFIG[board.hostbridge.userNetPorts] ?= "5555=5555,8080=80,8022=22" +FVP_CONFIG[board.hostbridge.userNetPorts] ?= "5555=5555,8080=80,2222=22" FVP_CONFIG[board.se_flash_size] ?= "8192" FVP_CONFIG[diagnostics] ?= "4" FVP_CONFIG[disable_visualisation] ?= "true" diff --git a/meta-arm/meta-arm-bsp/conf/machine/fvp-baser-aemv8r64.conf b/meta-arm/meta-arm-bsp/conf/machine/fvp-baser-aemv8r64.conf deleted file mode 100644 index 7d2eaf9b94..0000000000 --- a/meta-arm/meta-arm-bsp/conf/machine/fvp-baser-aemv8r64.conf +++ /dev/null @@ -1,66 +0,0 @@ -# Configuration for Fixed Virtual Platform BaseR AEMv8r64 Machine - -#@TYPE: Machine -#@NAME: FVP BaseR AEMv8r64 Machine -#@DESCRIPTION: Machine configuration for FVP BaseR AEMv8r64 - -require conf/machine/include/arm/armv8r/arch-armv8r64.inc - -EXTRA_IMAGEDEPENDS += "boot-wrapper-aarch64" - -PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto" -PREFERRED_VERSION_u-boot ?= "2023.01" - -KERNEL_IMAGETYPE = "Image" -KERNEL_DEVICETREE = "arm/fvp-baser-aemv8r64.dtb" - -UBOOT_MACHINE ?= "vexpress_aemv8r_defconfig" - -SERIAL_CONSOLES = "115200;ttyAMA0" - -IMAGE_CLASSES:append = " fvpboot" -IMAGE_FSTYPES += "wic" -WKS_FILE ?= "efi-disk.wks.in" -EFI_PROVIDER ?= "grub-efi" -MACHINE_FEATURES:append = " efi" - -IMAGE_NAME_SUFFIX = "" - -# As this is a virtual target that will not be used in the real world there is -# no need for real SSH keys. -MACHINE_EXTRA_RRECOMMENDS += "ssh-pregen-hostkeys" - -# testimage configuration -TEST_TARGET = "OEFVPTarget" -TEST_SUITES:append = " fvp_boot fvp_devices" -TEST_TARGET_IP ?= "127.0.0.1:8022" -TEST_SERVER_IP ?= "127.0.1.1" -TEST_FVP_DEVICES ?= "rtc watchdog networking virtiorng cpu_hotplug" - -FVP_EXTRA_ARGS = "-a cluster0*=linux-system.axf" -FVP_PROVIDER ?= "fvp-base-r-aem-native" -FVP_EXE ?= "FVP_BaseR_AEMv8R" -FVP_CONSOLE ?= "terminal_0" - -# FVP parameters -FVP_CONFIG[bp.exclusive_monitor.monitor_access_level] ?= "2" -FVP_CONFIG[bp.refcounter.non_arch_start_at_default] ?= "1" -FVP_CONFIG[bp.refcounter.use_real_time] ?= "1" -FVP_CONFIG[bp.ve_sysregs.exit_on_shutdown] ?= "1" -FVP_CONFIG[bp.virtio_net.enabled] ?= "1" -FVP_CONFIG[bp.virtio_net.hostbridge.userNetPorts] ?= "8022=22" -FVP_CONFIG[bp.virtio_net.hostbridge.userNetworking] ?= "1" -FVP_CONFIG[bp.virtio_net.secure_accesses] = "1" -FVP_CONFIG[bp.virtio_rng.enabled] ?= "1" -FVP_CONFIG[bp.virtio_rng.secure_accesses] = "1" -FVP_CONFIG[bp.virtioblockdevice.image_path] ?= "${IMAGE_NAME}.wic" -FVP_CONFIG[bp.virtioblockdevice.secure_accesses] = "1" -FVP_CONFIG[cache_state_modelled] ?= "0" -FVP_CONFIG[cci400.force_on_from_start] = "1" -FVP_CONFIG[cluster0.gicv3.cpuintf-mmap-access-level] ?= "2" -FVP_CONFIG[cluster0.gicv3.extended-interrupt-range-support] ?= "1" -FVP_CONFIG[cluster0.gicv3.SRE-EL2-enable-RAO] ?= "1" -FVP_CONFIG[cluster0.gicv3.SRE-enable-action-on-mmap] ?= "2" -FVP_CONFIG[cluster0.has_aarch64] ?= "1" -FVP_CONFIG[gic_distributor.GICD_CTLR-DS-1-means-secure-only] ?= "1" -FVP_CONFIG[gic_distributor.has-two-security-states] ?= "0" diff --git a/meta-arm/meta-arm-bsp/conf/machine/include/arm/armv8r/arch-armv8r64.inc b/meta-arm/meta-arm-bsp/conf/machine/include/arm/armv8r/arch-armv8r64.inc deleted file mode 100644 index 5db12e2c5d..0000000000 --- a/meta-arm/meta-arm-bsp/conf/machine/include/arm/armv8r/arch-armv8r64.inc +++ /dev/null @@ -1,10 +0,0 @@ -require conf/machine/include/arm/arch-armv8r.inc - -TUNE_FEATURES:tune-armv8r =+ "aarch64" -PACKAGE_EXTRA_ARCHS:tune-armv8r =+ "aarch64" -BASE_LIB:tune-armv8r = "lib64" -BASE_LIB:tune-armv8r-crc = "lib64" -BASE_LIB:tune-armv8r-crypto = "lib64" -BASE_LIB:tune-armv8r-simd = "lib64" -BASE_LIB:tune-armv8r-crc-simd = "lib64" -BASE_LIB:tune-armv8r-crc-crypto-simd = "lib64" diff --git a/meta-arm/meta-arm-bsp/conf/machine/include/corstone1000.inc b/meta-arm/meta-arm-bsp/conf/machine/include/corstone1000.inc index 72c0af518d..5a66f54d20 100644 --- a/meta-arm/meta-arm-bsp/conf/machine/include/corstone1000.inc +++ b/meta-arm/meta-arm-bsp/conf/machine/include/corstone1000.inc @@ -52,7 +52,7 @@ EXTRA_IMAGEDEPENDS += "external-system" # Linux kernel PREFERRED_PROVIDER_virtual/kernel:forcevariable = "linux-yocto" -PREFERRED_VERSION_linux-yocto = "6.1%" +PREFERRED_VERSION_linux-yocto = "6.4%" KERNEL_IMAGETYPE = "Image.gz" INITRAMFS_IMAGE_BUNDLE ?= "1" diff --git a/meta-arm/meta-arm-bsp/conf/machine/include/fvp-common.inc b/meta-arm/meta-arm-bsp/conf/machine/include/fvp-common.inc index 36bf9555e8..e6e4443199 100644 --- a/meta-arm/meta-arm-bsp/conf/machine/include/fvp-common.inc +++ b/meta-arm/meta-arm-bsp/conf/machine/include/fvp-common.inc @@ -23,7 +23,7 @@ EXTRA_IMAGEDEPENDS += "trusted-firmware-a" MACHINE_EXTRA_RRECOMMENDS += "ssh-pregen-hostkeys" TEST_TARGET = "OEFVPTarget" -TEST_TARGET_IP = "127.0.0.1:8022" +TEST_TARGET_IP = "127.0.0.1:2222" TEST_SUITES:append = " fvp_boot fvp_devices" TEST_FVP_DEVICES ?= "rtc watchdog networking virtiorng cpu_hotplug" @@ -32,8 +32,8 @@ FVP_EXE ?= "FVP_Base_RevC-2xAEMvA" FVP_CONFIG[bp.ve_sysregs.exit_on_shutdown] ?= "1" FVP_CONFIG[bp.virtio_net.enabled] ?= "1" FVP_CONFIG[bp.virtio_net.hostbridge.userNetworking] ?= "1" -# Tell testimage to connect to localhost:8022, and forward that to SSH in the FVP. -FVP_CONFIG[bp.virtio_net.hostbridge.userNetPorts] = "8022=22" +# Tell testimage to connect to localhost:2222, and forward that to SSH in the FVP. +FVP_CONFIG[bp.virtio_net.hostbridge.userNetPorts] = "2222=22" FVP_CONFIG[cache_state_modelled] ?= "0" FVP_CONFIG[bp.secureflashloader.fname] ?= "bl1-fvp.bin" FVP_CONFIG[bp.flashloader0.fname] ?= "fip-fvp.bin" diff --git a/meta-arm/meta-arm-bsp/conf/machine/n1sdp.conf b/meta-arm/meta-arm-bsp/conf/machine/n1sdp.conf index c25a32dcff..b93e053d1f 100644 --- a/meta-arm/meta-arm-bsp/conf/machine/n1sdp.conf +++ b/meta-arm/meta-arm-bsp/conf/machine/n1sdp.conf @@ -19,7 +19,7 @@ WKS_FILE_DEPENDS:append = " ${EXTRA_IMAGEDEPENDS}" # Use kernel provided by yocto PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto" -PREFERRED_VERSION_linux-yocto ?= "6.1%" +PREFERRED_VERSION_linux-yocto ?= "6.4%" # RTL8168E Gigabit Ethernet Controller is attached to the PCIe interface MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "linux-firmware-rtl8168" @@ -32,7 +32,7 @@ EXTRA_IMAGEDEPENDS += "edk2-firmware" PREFERRED_VERSION_edk2-firmware ?= "202305" #optee -PREFERRED_VERSION_optee-os ?= "3.20.%" +PREFERRED_VERSION_optee-os ?= "3.22.%" #grub-efi EFI_PROVIDER ?= "grub-efi" diff --git a/meta-arm/meta-arm-bsp/conf/machine/tc1.conf b/meta-arm/meta-arm-bsp/conf/machine/tc1.conf index 31bcc2fb06..a0f2967bb9 100644 --- a/meta-arm/meta-arm-bsp/conf/machine/tc1.conf +++ b/meta-arm/meta-arm-bsp/conf/machine/tc1.conf @@ -19,7 +19,7 @@ FVP_CONFIG[css.trustedBootROMloader.fname] ?= "bl1-tc.bin" FVP_CONFIG[board.flashloader0.fname] ?= "fip_gpt-tc.bin" #FVP_CONFIG[board.hostbridge.userNetworking] ?= "true" -#FVP_CONFIG[board.hostbridge.userNetPorts] ?= "8022=22" +#FVP_CONFIG[board.hostbridge.userNetPorts] ?= "2222=22" #smsc ethernet takes a very long time to come up. disable now to prevent testimage timeout #FVP_CONFIG[board.smsc_91c111.enabled] ?= "1" diff --git a/meta-arm/meta-arm-bsp/documentation/fvp-baser-aemv8r64.md b/meta-arm/meta-arm-bsp/documentation/fvp-baser-aemv8r64.md deleted file mode 100644 index 2635e75d79..0000000000 --- a/meta-arm/meta-arm-bsp/documentation/fvp-baser-aemv8r64.md +++ /dev/null @@ -1,264 +0,0 @@ -Armv8-R AArch64 AEM FVP Support in meta-arm-bsp -=============================================== - -Overview --------- - -Fixed Virtual Platforms (FVP) are complete simulations of an Arm system, -including processor, memory and peripherals. These are set out in a -"programmer's view", which gives you a comprehensive model on which to build -and test your software. - -The Armv8-R AEM FVP is a free of charge Armv8-R Fixed Virtual Platform. It -supports the latest Armv8-R feature set. - -This BSP implements a reference stack for the AArch64 support in the R-class -first announced with the Cortex-R82 processor: -https://developer.arm.com/ip-products/processors/cortex-r/cortex-r82 - -Fast Models Fixed Virtual Platforms (FVP) Reference Guide: -https://developer.arm.com/docs/100966/latest - - -BSP Support ------------ - -The fvp-baser-aemv8r64 Yocto MACHINE supports the following BSP components, -where either a standard or Real-Time Linux kernel (PREEMPT\_RT) can be built -and run: - - - FVP_Base_AEMv8R: v11.22.14 - - boot-wrapper-aarch64: provides PSCI support - - U-Boot: v2022.07 - provides UEFI services - - Linux kernel: linux-yocto-5.15 - - Linux kernel with PREEMPT\_RT support: linux-yocto-rt-5.15 - -Note that the Real-Time Linux kernel (PREEMPT\_RT) does not use the real-time -architectural extensions of the Armv8-R feature set. - -High-Level Architecture ------------------------ - -The diagram below shows the current boot flow: - - +---------------------------------------------------------------+ - | Linux kernel | - +---------------------------------------------------------------+ - /|\ /|\ - | | - | UEFI services | - | PSCI services | - \|/ | - +----------------+ | S-EL1 - ----| U-Boot |------------------------------|----------- - +----------------+ | S-EL2 - /|\ | - | | - | | - | | - +--------------------------------------------------\|/----------+ - | +----------------+ +----------------+ | - | boot-wrapper-aarch64 | Device tree | | PSCI handler | | - | +----------------+ +----------------+ | - +---------------------------------------------------------------+ - - -The firmware binary (generated as `linux-system.axf`) includes -boot-wrapper-aarch64, the flattened device tree and U-Boot. U-Boot is configured -to automatically detect a virtio block device and boot the UEFI payload at the -path `/efi/boot/bootaa64.efi`. Using the standard build, the first partition -contains a Grub image at this path, which boots the Linux kernel at `/Image` on -the same partition. The second partition of the image contains the Linux root -file system. - -There is no EL3 or non-secure world in the Armv8-R AArch64 architecture, so the -reset vector starts boot-wrapper-aarch64 at S-EL2. Boot-wrapper-aarch64 is -compiled with the `--enable-keep-el` flag, which causes it to boot U-Boot at -S-EL2 too. U-Boot is compiled with the `CONFIG_ARMV8_SWITCH_TO_EL1` flag, which -causes it to switch to S-EL1 before booting Linux. - -The bundled device tree is passed to U-Boot via register x0. U-Boot passes the -same device tree to Linux via the UEFI system table. - -Power state management is provided by PSCI services in boot-wrapper-aarch64. -Linux accesses the PSCI handler via HVC calls to S-EL2. U-Boot has been patched -to prevent it from overriding the exception vector at S-EL2. The PSCI handler -memory region is added to a `/memreserve/` node in the device tree. - -Please note that the final firmware architecture for the fvp-baser-aemv8r64 is -not yet stabilized. The patches in this layer are provided for development and -evaluation purposes only, and should not be used in production firmware. - -Quick start: Howto Build and Run --------------------------------- - -### Host environment setup -The following instructions have been tested on hosts running Ubuntu 18.04 and -Ubuntu 20.04. -Install the required packages for the build host: -https://docs.yoctoproject.org/singleindex.html#required-packages-for-the-build-host - -Kas is a setup tool for bitbake based projects. The minimal supported version -is 3.0, install it like so: - - pip3 install --user --upgrade kas - -For more details on kas, see https://kas.readthedocs.io/. - -To build the images for the fvp-baser-aemv8r64 machine, you also need to accept -the EULA at -https://developer.arm.com/downloads/-/arm-ecosystem-fvps/eula -by setting the following environment variable: - - ARM_FVP_EULA_ACCEPT="True" - -**Note:** The host machine should have at least 50 GBytes of free disk space -for the next steps to work correctly. - -### Fetch sources -To fetch and build the ongoing development of the software stack follow the -instructions on this document. - -To fetch and build the version 1 (single core) find instructions at https://community.arm.com/developer/tools-software/oss-platforms/w/docs/633/release-1-single-core - -To fetch and build the version 2 (linux smp) find instructions at https://community.arm.com/developer/tools-software/oss-platforms/w/docs/634/release-2---smp - -Fetch the meta-arm repository into a build directory: - - mkdir -p ~/fvp-baser-aemv8r64-build - cd ~/fvp-baser-aemv8r64-build - git clone https://git.yoctoproject.org/git/meta-arm - - -### Build -Building with the standard Linux kernel: - - cd ~/fvp-baser-aemv8r64-build - export ARM_FVP_EULA_ACCEPT="True" - kas build meta-arm/kas/fvp-baser-aemv8r64-bsp.yml - -Building with the Real-Time Linux kernel (PREEMPT\_RT): - - cd ~/fvp-baser-aemv8r64-build - export ARM_FVP_EULA_ACCEPT="True" - kas build meta-arm/kas/fvp-baser-aemv8r64-rt-bsp.yml - -### Run -To run an image after the build is done with the standard Linux kernel: - - kas shell --keep-config-unchanged \ - meta-arm/kas/fvp-baser-aemv8r64-bsp.yml \ - --command "../layers/meta-arm/scripts/runfvp \ - --console " - -To run an image after the build is done with the Real-Time Linux kernel -(PREEMPT\_RT): - - kas shell --keep-config-unchanged \ - meta-arm/kas/fvp-baser-aemv8r64-rt-bsp.yml \ - --command "../layers/meta-arm/scripts/runfvp \ - --console " - -**Note:** The terminal console login is `root` without password. - -To finish the fvp emulation, you need to close the telnet session: - - - Escape to telnet console with ``ctrl+]``. - - Run ``quit`` to close the session. - -### Networking -The FVP is configured by default to use "user-mode networking", which simulates -an IP router and DHCP server to avoid additional host dependencies and -networking configuration. Outbound connections work automatically, e.g. by -running: - - wget www.arm.com - -Inbound connections require an explicit port mapping from the host. By default, -port 8022 on the host is mapped to port 22 on the FVP, so that the following -command will connect to an ssh server running on the FVP: - - ssh root@localhost -p 8022 - -Note that user-mode networking does not support ICMP, so `ping` will not work. -For more information about user-mode networking, please see -https://developer.arm.com/documentation/100964/1117/Introduction-to-Fast-Models/User-mode-networking?lang=en - -### File sharing between host and fvp -It is possible to share a directory between the host machine and the fvp using -the virtio P9 device component included in the kernel. To do so, create a -directory to be mounted from the host machine: - - mkdir /path/to/host-mount-dir - -Then, add the following parameter containing the path to the directory when -launching the model: - - --parameter 'bp.virtiop9device.root_path=/path/to/host-mount-dir' - -e.g. for the standard Linux kernel: - - kas shell --keep-config-unchanged \ - meta-arm/kas/fvp-baser-aemv8r64-bsp.yml \ - --command "../layers/meta-arm/scripts/runfvp \ - --console -- --parameter \ - 'bp.virtiop9device.root_path=/path/to/host-mount-dir'" - -Once you are logged into the fvp, the host directory can be mounted in a -directory on the model using the following command: - - mount -t 9p -o trans=virtio,version=9p2000.L FM /path/to/fvp-mount-dir - -Devices supported in the kernel -------------------------------- - -- serial -- virtio 9p -- virtio disk -- virtio network -- virtio rng -- watchdog -- rtc - -Known Issues and Limitations ----------------------------- - -- Only PSCI CPU\_ON and CPU\_OFF functions are supported -- Linux kernel does not support booting from secure EL2 on Armv8-R AArch64 -- Linux KVM does not support Armv8-R AArch64 -- Device DMA memory cache-coherence issue: the FVP `cache_state_modelled` - parameter will affect the cache coherence behavior of peripherals’ DMA. When - users set `cache_state_modelled=1`, they also have to set - `cci400.force_on_from_start=1` to force the FVP to enable snooping on upstream - ports. - -Change Log ----------- -- Enabled the ability for U-Boot to apply device tree overlays -- Fixed bug in U-Boot that caused changes to the `memory` node in the device - tree to be ignored. -- Added boot-wrapper-aarch64 support for booting SMP payloads at S-EL2. -- Enabled testimage support by default. -- Added virtio\_rng to improve random number generation. -- Added U-Boot v2022.01 for UEFI support. -- Updated Linux kernel version from 5.14 to 5.15 for both standard and - Real-Time (PREEMPT\_RT) builds. -- Updated boot-wrapper-aarch64 revision and added support for booting U-Boot. -- Included boot-wrapper-aarch64 PSCI services in `/memreserve/` region. -- Fixed the counter frequency initialization in boot-wrapper-aarch64. -- Configured the FVP to use the default RAM size of 4 Gb -- Fixed PL011 and SP805 register sizes in the device tree. -- Added virtio\_net User Networking mode by default and removed instructions - about tap networking setup. -- Updated Linux kernel version from 5.10 to 5.14 for both standard and - Real-Time (PREEMPT\_RT) builds. -- Enabled SMP support via boot-wrapper-aarch64 providing the PSCI CPU\_ON and - CPU\_OFF functions. -- Introduced Armv8-R64 compiler flags. -- Added Linux PREEMPT\_RT support via linux-yocto-rt-5.10. -- Added support for file sharing with the host machine using Virtio P9. -- Added support for runfvp. -- Added performance event support (PMU) in the Linux device tree. -- Introduced the fvp-baser-aemv8r64 machine and its BSP composed of - boot-wrapper-aarch64 and linux-yocto-5.10 supporting serial, virtio disk, - virtio network, watchdog and rtc. diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64-fvp-baser-aemv8r64.inc b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64-fvp-baser-aemv8r64.inc deleted file mode 100644 index 8ffa0aa2e0..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64-fvp-baser-aemv8r64.inc +++ /dev/null @@ -1,36 +0,0 @@ -COMPATIBLE_MACHINE = "fvp-baser-aemv8r64" - -FILESEXTRAPATHS:prepend := "${THISDIR}/files/${MACHINE}:" -SRC_URI:append = " \ - file://0001-aarch64-Rename-labels-and-prepare-for-lower-EL-booti.patch \ - file://0002-aarch64-Prepare-for-EL1-booting.patch \ - file://0003-aarch64-Prepare-for-lower-EL-booting.patch \ - file://0004-gic-v3-Prepare-for-gicv3-with-EL2.patch \ - file://0005-aarch64-Prepare-for-booting-with-EL2.patch \ - file://0006-aarch64-Introduce-EL2-boot-code-for-Armv8-R-AArch64.patch \ - file://0007-Allow-enable-psci-to-choose-between-smc-and-hvc.patch \ - file://0008-aarch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch \ - file://0009-lds-Mark-the-mem-range.patch \ - file://0010-common-Introduce-the-libfdt.patch \ - file://0011-common-Add-essential-libc-functions.patch \ - file://0012-Makefile-Add-the-libfdt-to-the-Makefile-system.patch \ - file://0013-platform-Add-print_hex-func.patch \ - file://0014-common-Add-mem-usage-to-memreserve.patch \ - file://0015-boot-Add-the-enable-keep-el-compile-option.patch \ - file://0016-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch \ - file://0017-PSCI-Apply-flush-cache-after-setting-branch_data.patch \ - file://0018-PSCI-Add-function-call-entry-point.patch \ - file://0019-lds-Rearrange-and-mark-the-sections.patch \ - file://0020-common-Provide-firmware-info-using-libfdt.patch \ - file://0021-boot-Enable-firmware-node-initialization.patch \ - " - -BOOT_WRAPPER_AARCH64_CMDLINE = "\ -earlycon console=ttyAMA0 loglevel=8 rootfstype=ext4 root=/dev/vda1 rw" - -EXTRA_OECONF += "--enable-psci=hvc --enable-keep-el" - -TUNE_CCARGS = "" - -BOOT_WRAPPER_AARCH64_KERNEL = "u-boot.bin" -do_deploy[depends] += "u-boot:do_deploy" diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64_%.bbappend b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64_%.bbappend deleted file mode 100644 index c2e7e6e3ff..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/boot-wrapper-aarch64_%.bbappend +++ /dev/null @@ -1,4 +0,0 @@ -MACHINE_BOOT_WRAPPER_AARCH64_REQUIRE ?= "" -MACHINE_BOOT_WRAPPER_AARCH64_REQUIRE:fvp-baser-aemv8r64 ?= "boot-wrapper-aarch64-fvp-baser-aemv8r64.inc" - -require ${MACHINE_BOOT_WRAPPER_AARCH64_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0001-aarch64-Rename-labels-and-prepare-for-lower-EL-booti.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0001-aarch64-Rename-labels-and-prepare-for-lower-EL-booti.patch deleted file mode 100644 index 31fd515228..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0001-aarch64-Rename-labels-and-prepare-for-lower-EL-booti.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 545f6950ae4dc55b4974986aa9629adb16eaf4e1 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] aarch64: Rename labels and prepare for lower EL booting - -Prepare for booting from lower EL. Rename *_el3 relavant labels with -*_el_max and *_no_el3 with *_keep_el. Since the original _no_el3 means -"We neither do init sequence at this highest EL nor drop to lower EL -when entering to kernel", we rename it with _keep_el to make it more -clear for lower EL initialisation. - -Upstream-Status: Pending -Signed-off-by: Jaxson Han ---- - arch/aarch64/boot.S | 28 ++++++++++++++++++++-------- - arch/aarch64/psci.S | 9 +++++---- - arch/aarch64/spin.S | 4 ++-- - 3 files changed, 27 insertions(+), 14 deletions(-) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index d682ba5..fab694e 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -34,18 +34,30 @@ ASM_FUNC(_start) - - /* - * EL3 initialisation -+ * Boot sequence -+ * If CurrentEL == EL3, then goto EL3 initialisation and drop to -+ * lower EL before entering the kernel. -+ * Else, no initialisation and keep the current EL before -+ * entering the kernel. - */ - mrs x0, CurrentEL - cmp x0, #CURRENTEL_EL3 -- b.eq 1f -+ b.eq el3_init - -+ /* -+ * We stay in the current EL for entering the kernel -+ */ - mov w0, #1 -- ldr x1, =flag_no_el3 -+ ldr x1, =flag_keep_el - str w0, [x1] - -- b start_no_el3 -+ b start_keep_el - --1: mov x0, #0x30 // RES1 -+ /* -+ * EL3 initialisation -+ */ -+el3_init: -+ mov x0, #0x30 // RES1 - orr x0, x0, #(1 << 0) // Non-secure EL1 - orr x0, x0, #(1 << 8) // HVC enable - -@@ -145,7 +157,7 @@ ASM_FUNC(_start) - - bl gic_secure_init - -- b start_el3 -+ b start_el_max - - err_invalid_id: - b . -@@ -172,7 +184,7 @@ ASM_FUNC(jump_kernel) - bl find_logical_id - bl setup_stack // Reset stack pointer - -- ldr w0, flag_no_el3 -+ ldr w0, flag_keep_el - cmp w0, #0 // Prepare Z flag - - mov x0, x20 -@@ -181,7 +193,7 @@ ASM_FUNC(jump_kernel) - mov x3, x23 - - b.eq 1f -- br x19 // No EL3 -+ br x19 // Keep current EL - - 1: mov x4, #SPSR_KERNEL - -@@ -199,5 +211,5 @@ ASM_FUNC(jump_kernel) - - .data - .align 3 --flag_no_el3: -+flag_keep_el: - .long 0 -diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S -index 8bd224b..7b8919a 100644 ---- a/arch/aarch64/psci.S -+++ b/arch/aarch64/psci.S -@@ -79,7 +79,7 @@ smc_exit: - ldp x18, x19, [sp], #16 - eret - --ASM_FUNC(start_el3) -+ASM_FUNC(start_el_max) - ldr x0, =vector - bl setup_vector - -@@ -89,10 +89,11 @@ ASM_FUNC(start_el3) - b psci_first_spin - - /* -- * This PSCI implementation requires EL3. Without EL3 we'll only boot the -- * primary cpu, all others will be trapped in an infinite loop. -+ * This PSCI implementation requires the highest EL(EL3 or Armv8-R EL2). -+ * Without the highest EL, we'll only boot the primary cpu, all othersr -+ * will be trapped in an infinite loop. - */ --ASM_FUNC(start_no_el3) -+ASM_FUNC(start_keep_el) - cpuid x0, x1 - bl find_logical_id - cbz x0, psci_first_spin -diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S -index 1ea1c0b..bfb1d47 100644 ---- a/arch/aarch64/spin.S -+++ b/arch/aarch64/spin.S -@@ -12,8 +12,8 @@ - - .text - --ASM_FUNC(start_el3) --ASM_FUNC(start_no_el3) -+ASM_FUNC(start_el_max) -+ASM_FUNC(start_keep_el) - cpuid x0, x1 - bl find_logical_id - diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0002-aarch64-Prepare-for-EL1-booting.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0002-aarch64-Prepare-for-EL1-booting.patch deleted file mode 100644 index 4ef4507e79..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0002-aarch64-Prepare-for-EL1-booting.patch +++ /dev/null @@ -1,48 +0,0 @@ -From bad32d3fc127a421be416b17e4f7d6d514f06abb Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] aarch64: Prepare for EL1 booting - -When booting from EL1, add a check and skip the init of -sctlr_el2 in jump_kernel - -Upstream-Status: Pending -Signed-off-by: Jaxson Han -Reviewed-by: Andre Przywara ---- - arch/aarch64/boot.S | 6 +++++- - arch/aarch64/include/asm/cpu.h | 1 + - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index fab694e..5105b41 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -177,10 +177,14 @@ ASM_FUNC(jump_kernel) - ldr x0, =SCTLR_EL1_KERNEL - msr sctlr_el1, x0 - -+ mrs x0, CurrentEL -+ cmp x0, #CURRENTEL_EL2 -+ b.lt 1f -+ - ldr x0, =SCTLR_EL2_KERNEL - msr sctlr_el2, x0 - -- cpuid x0, x1 -+1: cpuid x0, x1 - bl find_logical_id - bl setup_stack // Reset stack pointer - -diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h -index 49d3f86..3767da3 100644 ---- a/arch/aarch64/include/asm/cpu.h -+++ b/arch/aarch64/include/asm/cpu.h -@@ -11,6 +11,7 @@ - - #define MPIDR_ID_BITS 0xff00ffffff - -+#define CURRENTEL_EL2 (2 << 2) - #define CURRENTEL_EL3 (3 << 2) - - /* diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0003-aarch64-Prepare-for-lower-EL-booting.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0003-aarch64-Prepare-for-lower-EL-booting.patch deleted file mode 100644 index c621187bfc..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0003-aarch64-Prepare-for-lower-EL-booting.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 252cbd36e51414b60ab68306f9c38e358709494d Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] aarch64: Prepare for lower EL booting - -Save SPSR_KERNEL into spsr_to_elx during el3_init. -The jump_kernel will load spsr_to_elx into spsr_el3. - -This change will make it easier to control whether drop to lower EL -before jumping to the kernel. - -Upstream-Status: Pending -Signed-off-by: Jaxson Han -Reviewed-by: Andre Przywara ---- - arch/aarch64/boot.S | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index 5105b41..243198d 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -151,7 +151,16 @@ el3_init: - mov x0, #ZCR_EL3_LEN_MAX // SVE: Enable full vector len - msr ZCR_EL3, x0 // for EL2. - --1: -+ /* -+ * Save SPSR_KERNEL into spsr_to_elx. -+ * The jump_kernel will load spsr_to_elx into spsr_el3 -+ */ -+1: mov w0, #SPSR_KERNEL -+ ldr x1, =spsr_to_elx -+ str w0, [x1] -+ b el_max_init -+ -+el_max_init: - ldr x0, =COUNTER_FREQ - msr cntfrq_el0, x0 - -@@ -199,7 +208,7 @@ ASM_FUNC(jump_kernel) - b.eq 1f - br x19 // Keep current EL - --1: mov x4, #SPSR_KERNEL -+1: ldr w4, spsr_to_elx - - /* - * If bit 0 of the kernel address is set, we're entering in AArch32 -@@ -217,3 +226,5 @@ ASM_FUNC(jump_kernel) - .align 3 - flag_keep_el: - .long 0 -+spsr_to_elx: -+ .long 0 diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0004-gic-v3-Prepare-for-gicv3-with-EL2.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0004-gic-v3-Prepare-for-gicv3-with-EL2.patch deleted file mode 100644 index 43885b93d8..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0004-gic-v3-Prepare-for-gicv3-with-EL2.patch +++ /dev/null @@ -1,105 +0,0 @@ -From bff110a95a5e4c9db2d61e629b4aa4b84530201e Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] gic-v3: Prepare for gicv3 with EL2 - -This is a preparation for allowing boot-wrapper configuring the gicv3 -with EL2. - -When confiuring with EL2, since there is no ICC_CTLR_EL2, the -ICC_CTLR_EL3 cannot be replaced with ICC_CTLR_EL2 simply. -See [https://developer.arm.com/documentation/ihi0069/latest/]. - -As the caller, gic_secure_init expects the ICC_CTLR to be written, -we change the function into gic_init_icc_ctlr(). In the GIC spec, -the r/w bits in this register ([6:0]) either affect EL3 IRQ routing -(not applicable since no EL3), non-secure IRQ handling (not applicable -since only secure state in Armv8-R aarch64), or are aliased to -ICC_CTLR_EL1 bits. -So, based on this, the new gic_init_icc_ctlr() would be: -When currentEL is EL3, init ICC_CTLR_EL3 as before. -When currentEL is not EL3, init ICC_CTLR_EL1 with ICC_CTLR_EL1_RESET. - -Upstream-Status: Pending -Signed-off-by: Jaxson Han -Reviewed-by: Andre Przywara ---- - arch/aarch32/include/asm/gic-v3.h | 7 +++++++ - arch/aarch64/include/asm/gic-v3.h | 23 ++++++++++++++++++++--- - common/gic-v3.c | 2 +- - 3 files changed, 28 insertions(+), 4 deletions(-) - -diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h -index 65f38de..11e7bc7 100644 ---- a/arch/aarch32/include/asm/gic-v3.h -+++ b/arch/aarch32/include/asm/gic-v3.h -@@ -9,6 +9,8 @@ - #ifndef __ASM_AARCH32_GICV3_H - #define __ASM_AARCH32_GICV3_H - -+#define ICC_CTLR_RESET (0UL) -+ - static inline void gic_write_icc_sre(uint32_t val) - { - asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val)); -@@ -19,4 +21,9 @@ static inline void gic_write_icc_ctlr(uint32_t val) - asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val)); - } - -+static inline void gic_init_icc_ctlr() -+{ -+ gic_write_icc_ctlr(ICC_CTLR_RESET); -+} -+ - #endif -diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h -index 5b32380..090ab0b 100644 ---- a/arch/aarch64/include/asm/gic-v3.h -+++ b/arch/aarch64/include/asm/gic-v3.h -@@ -15,14 +15,31 @@ - #define ICC_CTLR_EL3 "S3_6_C12_C12_4" - #define ICC_PMR_EL1 "S3_0_C4_C6_0" - -+#define ICC_CTLR_EL3_RESET (0UL) -+#define ICC_CTLR_EL1_RESET (0UL) -+ -+static inline uint32_t current_el(void) -+{ -+ uint32_t val; -+ -+ asm volatile ("mrs %0, CurrentEL" : "=r" (val)); -+ return val; -+} -+ - static inline void gic_write_icc_sre(uint32_t val) - { -- asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val)); -+ if (current_el() == CURRENTEL_EL3) -+ asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val)); -+ else -+ asm volatile ("msr " ICC_SRE_EL2 ", %0" : : "r" (val)); - } - --static inline void gic_write_icc_ctlr(uint32_t val) -+static inline void gic_init_icc_ctlr() - { -- asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val)); -+ if (current_el() == CURRENTEL_EL3) -+ asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (ICC_CTLR_EL3_RESET)); -+ else -+ asm volatile ("msr " ICC_CTLR_EL1 ", %0" : : "r" (ICC_CTLR_EL1_RESET)); - } - - #endif -diff --git a/common/gic-v3.c b/common/gic-v3.c -index 6207007..a0fe564 100644 ---- a/common/gic-v3.c -+++ b/common/gic-v3.c -@@ -117,6 +117,6 @@ void gic_secure_init(void) - gic_write_icc_sre(ICC_SRE_Enable | ICC_SRE_DIB | ICC_SRE_DFB | ICC_SRE_SRE); - isb(); - -- gic_write_icc_ctlr(0); -+ gic_init_icc_ctlr(); - isb(); - } diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0005-aarch64-Prepare-for-booting-with-EL2.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0005-aarch64-Prepare-for-booting-with-EL2.patch deleted file mode 100644 index c6343456a7..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0005-aarch64-Prepare-for-booting-with-EL2.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ba955efb35ce1d41b562190d7c2fbcbcf8ef97ff Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] aarch64: Prepare for booting with EL2 - -Prepare for allowing boot-wrapper to be entered in EL2. -Detect current EL and set the corresponding EL registers. - -Upstream-Status: Pending -Signed-off-by: Jaxson Han -Reviewed-by: Andre Przywara ---- - arch/aarch64/boot.S | 8 ++++++++ - arch/aarch64/utils.S | 10 +++++++++- - 2 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index 243198d..3593ca5 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -216,10 +216,18 @@ ASM_FUNC(jump_kernel) - */ - bfi x4, x19, #5, #1 - -+ mrs x5, CurrentEL -+ cmp x5, #CURRENTEL_EL2 -+ b.eq 1f -+ - msr elr_el3, x19 - msr spsr_el3, x4 - eret - -+1: msr elr_el2, x19 -+ msr spsr_el2, x4 -+ eret -+ - .ltorg - - .data -diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S -index 85c7f8a..f02a249 100644 ---- a/arch/aarch64/utils.S -+++ b/arch/aarch64/utils.S -@@ -34,10 +34,18 @@ ASM_FUNC(find_logical_id) - ret - - /* -- * Setup EL3 vectors -+ * Setup EL3/EL2 vectors - * x0: vector address - */ - ASM_FUNC(setup_vector) -+ mrs x1, CurrentEL -+ cmp x1, #CURRENTEL_EL2 -+ b.eq 1f -+ - msr VBAR_EL3, x0 - isb - ret -+ -+1: msr VBAR_EL2, x0 -+ isb -+ ret diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0006-aarch64-Introduce-EL2-boot-code-for-Armv8-R-AArch64.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0006-aarch64-Introduce-EL2-boot-code-for-Armv8-R-AArch64.patch deleted file mode 100644 index 18dc7ed7e4..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0006-aarch64-Introduce-EL2-boot-code-for-Armv8-R-AArch64.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 8e44fac113d935affed1550480631f3fe7f30584 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 May 2021 07:25:00 +0100 -Subject: [PATCH] aarch64: Introduce EL2 boot code for Armv8-R AArch64 - -The Armv8-R AArch64 profile does not support the EL3 exception level. -The Armv8-R AArch64 profile allows for an (optional) VMSAv8-64 MMU -at EL1, which allows to run off-the-shelf Linux. However EL2 only -supports a PMSA, which is not supported by Linux, so we need to drop -into EL1 before entering the kernel. - -We add a new err_invalid_arch symbol as a dead loop. If we detect the -current Armv8-R aarch64 only supports with PMSA, meaning we cannot boot -Linux anymore, then we jump to err_invalid_arch. - -During Armv8-R aarch64 init, to make sure nothing unexpected traps into -EL2, we auto-detect and config FIEN and EnSCXT in HCR_EL2. - -The boot sequence is: -If CurrentEL == EL3, then goto EL3 initialisation and drop to lower EL - before entering the kernel. -If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf (Armv8-R aarch64), - if id_aa64mmfr0_el1.MSA_frac == 0x2, - then goto Armv8-R AArch64 initialisation and drop to EL1 before - entering the kernel. - else, which means VMSA unsupported and cannot boot Linux, - goto err_invalid_arch (dead loop). -Else, no initialisation and keep the current EL before entering the - kernel. - -Upstream-Status: Pending -Signed-off-by: Jaxson Han ---- - arch/aarch64/boot.S | 92 +++++++++++++++++++++++++++++++++- - arch/aarch64/include/asm/cpu.h | 2 + - 2 files changed, 92 insertions(+), 2 deletions(-) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index 3593ca5..a219ea7 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -37,16 +37,24 @@ ASM_FUNC(_start) - * Boot sequence - * If CurrentEL == EL3, then goto EL3 initialisation and drop to - * lower EL before entering the kernel. -+ * If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf, then -+ * If id_aa64mmfr0_el1.MSA_frac == 0x2, then goto -+ * Armv8-R AArch64 initialisation and drop to EL1 before -+ * entering the kernel. -+ * Else, which means VMSA unsupported and cannot boot Linux, -+ * goto err_invalid_arch (dead loop). - * Else, no initialisation and keep the current EL before - * entering the kernel. - */ - mrs x0, CurrentEL -- cmp x0, #CURRENTEL_EL3 -- b.eq el3_init -+ cmp x0, #CURRENTEL_EL2 -+ bgt el3_init -+ beq el2_init - - /* - * We stay in the current EL for entering the kernel - */ -+keep_el: - mov w0, #1 - ldr x1, =flag_keep_el - str w0, [x1] -@@ -160,6 +168,85 @@ el3_init: - str w0, [x1] - b el_max_init - -+ /* -+ * EL2 Armv8-R AArch64 initialisation -+ */ -+el2_init: -+ /* Detect Armv8-R AArch64 */ -+ mrs x1, id_aa64mmfr0_el1 -+ /* -+ * Check MSA, bits [51:48]: -+ * 0xf means Armv8-R AArch64. -+ * If not 0xf, proceed in Armv8-A EL2. -+ */ -+ ubfx x0, x1, #48, #4 // MSA -+ cmp x0, 0xf -+ bne keep_el -+ /* -+ * Check MSA_frac, bits [55:52]: -+ * 0x2 means EL1&0 translation regime also supports VMSAv8-64. -+ */ -+ ubfx x0, x1, #52, #4 // MSA_frac -+ cmp x0, 0x2 -+ /* -+ * If not 0x2, no VMSA, so cannot boot Linux and dead loop. -+ * Also, since the architecture guarantees that those CPUID -+ * fields never lose features when the value in a field -+ * increases, we use blt to cover it. -+ */ -+ blt err_invalid_arch -+ -+ mrs x0, midr_el1 -+ msr vpidr_el2, x0 -+ -+ mrs x0, mpidr_el1 -+ msr vmpidr_el2, x0 -+ -+ mov x0, #(1 << 31) // VTCR_MSA: VMSAv8-64 support -+ msr vtcr_el2, x0 -+ -+ /* Init HCR_EL2 */ -+ mov x0, #(1 << 31) // RES1: Armv8-R aarch64 only -+ -+ mrs x1, id_aa64pfr0_el1 -+ ubfx x2, x1, #56, 4 // ID_AA64PFR0_EL1.CSV2 -+ cmp x2, 0x2 -+ b.lt 1f -+ /* -+ * Disable trap when accessing SCTXNUM_EL0 or SCTXNUM_EL1 -+ * if FEAT_CSV2. -+ */ -+ orr x0, x0, #(1 << 53) // HCR_EL2.EnSCXT -+ -+1: ubfx x2, x1, #28, 4 // ID_AA64PFR0_EL1.RAS -+ cmp x2, 0x2 -+ b.lt 1f -+ /* Disable trap when accessing ERXPFGCDN_EL1 if FEAT_RASv1p1. */ -+ orr x0, x0, #(1 << 47) // HCR_EL2.FIEN -+ -+ /* Enable pointer authentication if present */ -+1: mrs x1, id_aa64isar1_el1 -+ /* -+ * If ID_AA64ISAR1_EL1.{GPI, GPA, API, APA} == {0000, 0000, 0000, 0000} -+ * then HCR_EL2.APK and HCR_EL2.API are RES 0. -+ * Else -+ * set HCR_EL2.APK and HCR_EL2.API. -+ */ -+ ldr x2, =(((0xff) << 24) | (0xff << 4)) -+ and x1, x1, x2 -+ cbz x1, 1f -+ -+ orr x0, x0, #(1 << 40) // HCR_EL2.APK -+ orr x0, x0, #(1 << 41) // HCR_EL2.API -+ -+1: msr hcr_el2, x0 -+ isb -+ -+ mov w0, #SPSR_KERNEL_EL1 -+ ldr x1, =spsr_to_elx -+ str w0, [x1] -+ // fall through -+ - el_max_init: - ldr x0, =COUNTER_FREQ - msr cntfrq_el0, x0 -@@ -169,6 +256,7 @@ el_max_init: - b start_el_max - - err_invalid_id: -+err_invalid_arch: - b . - - /* -diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h -index 3767da3..3c0e00d 100644 ---- a/arch/aarch64/include/asm/cpu.h -+++ b/arch/aarch64/include/asm/cpu.h -@@ -25,6 +25,7 @@ - #define SPSR_I (1 << 7) /* IRQ masked */ - #define SPSR_F (1 << 6) /* FIQ masked */ - #define SPSR_T (1 << 5) /* Thumb */ -+#define SPSR_EL1H (5 << 0) /* EL1 Handler mode */ - #define SPSR_EL2H (9 << 0) /* EL2 Handler mode */ - #define SPSR_HYP (0x1a << 0) /* M[3:0] = hyp, M[4] = AArch32 */ - -@@ -50,6 +51,7 @@ - #else - #define SCTLR_EL1_KERNEL SCTLR_EL1_RES1 - #define SPSR_KERNEL (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H) -+#define SPSR_KERNEL_EL1 (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL1H) - #endif - - #ifndef __ASSEMBLY__ diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0007-Allow-enable-psci-to-choose-between-smc-and-hvc.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0007-Allow-enable-psci-to-choose-between-smc-and-hvc.patch deleted file mode 100644 index 131e271012..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0007-Allow-enable-psci-to-choose-between-smc-and-hvc.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0b9a966b8a28961b078215ee7169e32a976d5e7d Mon Sep 17 00:00:00 2001 -From: Qi Feng -Date: Wed, 26 May 2021 17:52:01 +0800 -Subject: [PATCH] Allow --enable-psci to choose between smc and hvc - -According to Armv8-R AArch64 manual [1], Armv8-R AArch64 does not -support smc: - -- Pseudocode for AArch64.CheckForSMCUndefOrTrap has this snippet: - - if !HaveEL(EL3) || PSTATE.EL == EL0 then - UNDEFINED; - - And Armv8-R AArch64 does not have EL3. - -- In the document of HCR_EL2 TSC bit: - If EL3 is not implemented and HCR_EL2.NV is 0, it is IMPLEMENTATION - DEFINED whether this bit is: - - RES0. - - Implemented with the functionality as described in HCR_EL2.TSC. - -So hvc is needed in this situation. And due to the lack of libfdt, the -psci method cannot be modified at runtime. - -To use smc, use --enable-psci or --enable-psci=smc. -To use hvc, use --enable-psci=hvc. - -[1]: https://developer.arm.com/documentation/ddi0600/latest/ - -Issue-Id: SCM-2654 -Upstream-Status: Pending -Signed-off-by: Qi Feng -Change-Id: Ib8afabdad2d98bc37371d165bbb6f1f9b88bfc87 - -Upstream-Status: Pending -Signed-off-by: Huifeng Zhang ---- - Makefile.am | 10 +++++----- - configure.ac | 14 +++++++++----- - 2 files changed, 14 insertions(+), 10 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index 5731a19..fc66662 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -50,11 +50,11 @@ endif - if PSCI - ARCH_OBJ += psci.o - COMMON_OBJ += psci.o --PSCI_NODE := psci { \ -- compatible = \"arm,psci\"; \ -- method = \"smc\"; \ -- cpu_on = <$(PSCI_CPU_ON)>; \ -- cpu_off = <$(PSCI_CPU_OFF)>; \ -+PSCI_NODE := psci { \ -+ compatible = \"arm,psci\"; \ -+ method = \"$(PSCI_METHOD)\"; \ -+ cpu_on = <$(PSCI_CPU_ON)>; \ -+ cpu_off = <$(PSCI_CPU_OFF)>; \ - }; - CPU_NODES := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/addpsci.pl $(KERNEL_DTB)) - else -diff --git a/configure.ac b/configure.ac -index 9e3b722..53e51be 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -83,13 +83,17 @@ AS_IF([test "x$X_IMAGE" != "x"], - # Allow a user to pass --enable-psci - AC_ARG_ENABLE([psci], - AS_HELP_STRING([--disable-psci], [disable the psci boot method]), -- [USE_PSCI=$enableval], [USE_PSCI="yes"]) --AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"]) --AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no]) -- --AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"], -+ [case "${enableval}" in -+ yes|smc) USE_PSCI=smc ;; -+ hvc) USE_PSCI=hvc ;; -+ *) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;; -+ esac], [USE_PSCI="yes"]) -+AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"]) -+ -+AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"], - [AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])] - ) -+AC_SUBST([PSCI_METHOD], [$USE_PSCI]) - - # Allow a user to pass --with-initrd - AC_ARG_WITH([initrd], diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0008-aarch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0008-aarch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch deleted file mode 100644 index d3ccb2ebe9..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0008-aarch64-Disable-CNTPCT_EL0-trap-for-v8-R64.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 521c121eccb386aca7c75d92528e495546adccec Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Mon, 25 Oct 2021 17:09:13 +0800 -Subject: [PATCH] aarch64: Disable CNTPCT_EL0 trap for v8-R64 - -To allow EL1 to access CNTPCT_EL0 without traping into EL2, we need to -set CNTHCTL_EL2.EL1PCTEN to 1. - -For v8-R64, the CNTHCTL_EL2 register follows the v8-A architecture. -However, as described in the v8-A architecture profile, the -CNTHCTL_EL2's bit assignments are different according to whether the -FEAT_VHE is implemented. - -Since v8-R64 does not support FEAT_VHE, we do not need to detect -FEAT_VHE. We can simply set CNTHCTL_EL2.EL1PCTEN to 1. - -Issue-ID: SCM-3508 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I4147e66341c8153312021e6f2ab67d0037246da1 ---- - arch/aarch64/boot.S | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index a219ea7..27b1139 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -240,6 +240,18 @@ el2_init: - orr x0, x0, #(1 << 41) // HCR_EL2.API - - 1: msr hcr_el2, x0 -+ -+ /* -+ * To disable trap when accessing CNTPCT_EL0, we need to set -+ * CNTHCTL_EL2.EL1PCTEN to 1. However, the CNTHCTL_EL2 bit assignments -+ * are different according to whether the FEAT_VHE is implemented. -+ * -+ * For Armv8-R AArch64, FEAT_VHE is not supported, so we do not need to -+ * detect FEAT_VHE(ID_AA64MMFR1_EL1.VH) and simply set -+ * CNTHCTL_EL2.EL1PCTEN to 1. -+ */ -+ mov x0, #1 // CNTHCTL_EL2.EL1PCTEN -+ msr cnthctl_el2, x0 - isb - - mov w0, #SPSR_KERNEL_EL1 diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0009-lds-Mark-the-mem-range.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0009-lds-Mark-the-mem-range.patch deleted file mode 100644 index c34d01c386..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0009-lds-Mark-the-mem-range.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 780df234d98db81485b1f351f902a68def35c9d4 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 2 Nov 2021 15:10:28 +0800 -Subject: [PATCH] lds: Mark the mem range - -Add firmware_start and firmware_end, so that we can use them to -calculate the mem range of boot-wrapper and then set the range to -/memreserve/ of dtb. - -Issue-ID: SCM-3815 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: Idc5a2894e193c75381049a0f359b4b2a51c567ee ---- - model.lds.S | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/model.lds.S b/model.lds.S -index d4e7e13..ab98ddf 100644 ---- a/model.lds.S -+++ b/model.lds.S -@@ -64,6 +64,7 @@ SECTIONS - #endif - - .boot PHYS_OFFSET: { -+ PROVIDE(firmware_start = .); - *(.init) - *(.text*) - *(.data* .rodata* .bss* COMMON) -@@ -76,6 +77,7 @@ SECTIONS - mbox = .; - QUAD(0x0) - } -+ PROVIDE(firmware_end = .); - - ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!") - } diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0010-common-Introduce-the-libfdt.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0010-common-Introduce-the-libfdt.patch deleted file mode 100644 index 2d12db593b..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0010-common-Introduce-the-libfdt.patch +++ /dev/null @@ -1,6044 +0,0 @@ -From b3762b6c5a56bf594bc5cb63d145e8efd86e106e Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 28 Dec 2021 17:02:17 +0800 -Subject: [PATCH] common: Introduce the libfdt - -We introduce libfdt (v1.6.1) [1] to boot-wrapper, so we can dynamically -add the firmware node. - -According to [2]: The libfdt is GPL/BSD dual-licensed which means it can -be used either under the terms of GPL, or under the terms of BSD. -We choose BSD because the boot-wrapper is under BSD. - -[1]: https://github.com/dgibson/dtc/tree/v1.6.1/libfdt -[2]: https://github.com/dgibson/dtc/blob/v1.6.1/README.license - -Issue-Id: SCM-3814 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: Iec2f469053c8ac0ed38838c597b21a42bdf67b38 ---- - common/libfdt/README.license | 56 + - common/libfdt/fdt.c | 335 +++++ - common/libfdt/fdt_addresses.c | 101 ++ - common/libfdt/fdt_check.c | 93 ++ - common/libfdt/fdt_empty_tree.c | 38 + - common/libfdt/fdt_overlay.c | 882 +++++++++++++ - common/libfdt/fdt_ro.c | 859 +++++++++++++ - common/libfdt/fdt_rw.c | 500 +++++++ - common/libfdt/fdt_strerror.c | 59 + - common/libfdt/fdt_sw.c | 384 ++++++ - common/libfdt/fdt_wip.c | 94 ++ - common/libfdt/libfdt_internal.h | 192 +++ - include/fdt.h | 66 + - include/libfdt.h | 2147 +++++++++++++++++++++++++++++++ - include/libfdt_env.h | 95 ++ - 15 files changed, 5901 insertions(+) - create mode 100644 common/libfdt/README.license - create mode 100644 common/libfdt/fdt.c - create mode 100644 common/libfdt/fdt_addresses.c - create mode 100644 common/libfdt/fdt_check.c - create mode 100644 common/libfdt/fdt_empty_tree.c - create mode 100644 common/libfdt/fdt_overlay.c - create mode 100644 common/libfdt/fdt_ro.c - create mode 100644 common/libfdt/fdt_rw.c - create mode 100644 common/libfdt/fdt_strerror.c - create mode 100644 common/libfdt/fdt_sw.c - create mode 100644 common/libfdt/fdt_wip.c - create mode 100644 common/libfdt/libfdt_internal.h - create mode 100644 include/fdt.h - create mode 100644 include/libfdt.h - create mode 100644 include/libfdt_env.h - -diff --git a/common/libfdt/README.license b/common/libfdt/README.license -new file mode 100644 -index 0000000..102b004 ---- /dev/null -+++ b/common/libfdt/README.license -@@ -0,0 +1,56 @@ -+Licensing and contribution policy of dtc and libfdt -+=================================================== -+ -+This dtc package contains two pieces of software: dtc itself, and -+libfdt which comprises the files in the libfdt/ subdirectory. These -+two pieces of software, although closely related, are quite distinct. -+dtc does not incorporate or rely on libfdt for its operation, nor vice -+versa. It is important that these two pieces of software have -+different license conditions. -+ -+As SPDX license tags in each source file attest, dtc is licensed -+under the GNU GPL. The full text of the GPL can be found in the file -+entitled 'GPL' which should be included in this package. dtc code, -+therefore, may not be incorporated into works which do not have a GPL -+compatible license. -+ -+libfdt, however, is GPL/BSD dual-licensed. That is, it may be used -+either under the terms of the GPL, or under the terms of the 2-clause -+BSD license (aka the ISC license). The full terms of that license can -+be found are in the file entitled 'BSD-2-Clause'. This is, in -+practice, equivalent to being BSD licensed, since the terms of the BSD -+license are strictly more permissive than the GPL. -+ -+I made the decision to license libfdt in this way because I want to -+encourage widespread and correct usage of flattened device trees, -+including by proprietary or otherwise GPL-incompatible firmware or -+tools. Allowing libfdt to be used under the terms of the BSD license -+makes that it easier for vendors or authors of such software to do so. -+ -+This does mean that libfdt code could be "stolen" - say, included in a -+proprietary fimware and extended without contributing those extensions -+back to the libfdt mainline. While I hope that doesn't happen, I -+believe the goal of allowing libfdt to be widely used is more -+important than avoiding that. libfdt is quite small, and hardly -+rocket science; so the incentive for such impolite behaviour is small, -+and the inconvenience caused thereby is not dire. -+ -+Licenses such as the LGPL which would allow code to be used in non-GPL -+software, but also require contributions to be returned were -+considered. However, libfdt is designed to be used in firmwares and -+other environments with unusual technical constraints. It's difficult -+to anticipate all possible changes which might be needed to meld -+libfdt into such environments and so difficult to suitably word a -+license that puts the boundary between what is and isn't permitted in -+the intended place. Again, I judged encouraging widespread use of -+libfdt by keeping the license terms simple and familiar to be the more -+important goal. -+ -+**IMPORTANT** It's intended that all of libfdt as released remain -+permissively licensed this way. Therefore only contributions which -+are released under these terms can be merged into the libfdt mainline. -+ -+ -+David Gibson -+(principal original author of dtc and libfdt) -+2 November 2007 -diff --git a/common/libfdt/fdt.c b/common/libfdt/fdt.c -new file mode 100644 -index 0000000..9fe7cf4 ---- /dev/null -+++ b/common/libfdt/fdt.c -@@ -0,0 +1,335 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+/* -+ * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks -+ * that the given buffer contains what appears to be a flattened -+ * device tree with sane information in its header. -+ */ -+int32_t fdt_ro_probe_(const void *fdt) -+{ -+ uint32_t totalsize = fdt_totalsize(fdt); -+ -+ if (can_assume(VALID_DTB)) -+ return totalsize; -+ -+ /* The device tree must be at an 8-byte aligned address */ -+ if ((uintptr_t)fdt & 7) -+ return -FDT_ERR_ALIGNMENT; -+ -+ if (fdt_magic(fdt) == FDT_MAGIC) { -+ /* Complete tree */ -+ if (!can_assume(LATEST)) { -+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) -+ return -FDT_ERR_BADVERSION; -+ if (fdt_last_comp_version(fdt) > -+ FDT_LAST_SUPPORTED_VERSION) -+ return -FDT_ERR_BADVERSION; -+ } -+ } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { -+ /* Unfinished sequential-write blob */ -+ if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0) -+ return -FDT_ERR_BADSTATE; -+ } else { -+ return -FDT_ERR_BADMAGIC; -+ } -+ -+ if (totalsize < INT32_MAX) -+ return totalsize; -+ else -+ return -FDT_ERR_TRUNCATED; -+} -+ -+static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) -+{ -+ return (off >= hdrsize) && (off <= totalsize); -+} -+ -+static int check_block_(uint32_t hdrsize, uint32_t totalsize, -+ uint32_t base, uint32_t size) -+{ -+ if (!check_off_(hdrsize, totalsize, base)) -+ return 0; /* block start out of bounds */ -+ if ((base + size) < base) -+ return 0; /* overflow */ -+ if (!check_off_(hdrsize, totalsize, base + size)) -+ return 0; /* block end out of bounds */ -+ return 1; -+} -+ -+size_t fdt_header_size_(uint32_t version) -+{ -+ if (version <= 1) -+ return FDT_V1_SIZE; -+ else if (version <= 2) -+ return FDT_V2_SIZE; -+ else if (version <= 3) -+ return FDT_V3_SIZE; -+ else if (version <= 16) -+ return FDT_V16_SIZE; -+ else -+ return FDT_V17_SIZE; -+} -+ -+size_t fdt_header_size(const void *fdt) -+{ -+ return can_assume(LATEST) ? FDT_V17_SIZE : -+ fdt_header_size_(fdt_version(fdt)); -+} -+ -+int fdt_check_header(const void *fdt) -+{ -+ size_t hdrsize; -+ -+ /* The device tree must be at an 8-byte aligned address */ -+ if ((uintptr_t)fdt & 7) -+ return -FDT_ERR_ALIGNMENT; -+ -+ if (fdt_magic(fdt) != FDT_MAGIC) -+ return -FDT_ERR_BADMAGIC; -+ if (!can_assume(LATEST)) { -+ if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) -+ || (fdt_last_comp_version(fdt) > -+ FDT_LAST_SUPPORTED_VERSION)) -+ return -FDT_ERR_BADVERSION; -+ if (fdt_version(fdt) < fdt_last_comp_version(fdt)) -+ return -FDT_ERR_BADVERSION; -+ } -+ hdrsize = fdt_header_size(fdt); -+ if (!can_assume(VALID_DTB)) { -+ -+ if ((fdt_totalsize(fdt) < hdrsize) -+ || (fdt_totalsize(fdt) > INT_MAX)) -+ return -FDT_ERR_TRUNCATED; -+ -+ /* Bounds check memrsv block */ -+ if (!check_off_(hdrsize, fdt_totalsize(fdt), -+ fdt_off_mem_rsvmap(fdt))) -+ return -FDT_ERR_TRUNCATED; -+ } -+ -+ if (!can_assume(VALID_DTB)) { -+ /* Bounds check structure block */ -+ if (!can_assume(LATEST) && fdt_version(fdt) < 17) { -+ if (!check_off_(hdrsize, fdt_totalsize(fdt), -+ fdt_off_dt_struct(fdt))) -+ return -FDT_ERR_TRUNCATED; -+ } else { -+ if (!check_block_(hdrsize, fdt_totalsize(fdt), -+ fdt_off_dt_struct(fdt), -+ fdt_size_dt_struct(fdt))) -+ return -FDT_ERR_TRUNCATED; -+ } -+ -+ /* Bounds check strings block */ -+ if (!check_block_(hdrsize, fdt_totalsize(fdt), -+ fdt_off_dt_strings(fdt), -+ fdt_size_dt_strings(fdt))) -+ return -FDT_ERR_TRUNCATED; -+ } -+ -+ return 0; -+} -+ -+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) -+{ -+ unsigned int uoffset = offset; -+ unsigned int absoffset = offset + fdt_off_dt_struct(fdt); -+ -+ if (offset < 0) -+ return NULL; -+ -+ if (!can_assume(VALID_INPUT)) -+ if ((absoffset < uoffset) -+ || ((absoffset + len) < absoffset) -+ || (absoffset + len) > fdt_totalsize(fdt)) -+ return NULL; -+ -+ if (can_assume(LATEST) || fdt_version(fdt) >= 0x11) -+ if (((uoffset + len) < uoffset) -+ || ((offset + len) > fdt_size_dt_struct(fdt))) -+ return NULL; -+ -+ return fdt_offset_ptr_(fdt, offset); -+} -+ -+uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) -+{ -+ const fdt32_t *tagp, *lenp; -+ uint32_t tag; -+ int offset = startoffset; -+ const char *p; -+ -+ *nextoffset = -FDT_ERR_TRUNCATED; -+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); -+ if (!can_assume(VALID_DTB) && !tagp) -+ return FDT_END; /* premature end */ -+ tag = fdt32_to_cpu(*tagp); -+ offset += FDT_TAGSIZE; -+ -+ *nextoffset = -FDT_ERR_BADSTRUCTURE; -+ switch (tag) { -+ case FDT_BEGIN_NODE: -+ /* skip name */ -+ do { -+ p = fdt_offset_ptr(fdt, offset++, 1); -+ } while (p && (*p != '\0')); -+ if (!can_assume(VALID_DTB) && !p) -+ return FDT_END; /* premature end */ -+ break; -+ -+ case FDT_PROP: -+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); -+ if (!can_assume(VALID_DTB) && !lenp) -+ return FDT_END; /* premature end */ -+ /* skip-name offset, length and value */ -+ offset += sizeof(struct fdt_property) - FDT_TAGSIZE -+ + fdt32_to_cpu(*lenp); -+ if (!can_assume(LATEST) && -+ fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && -+ ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) -+ offset += 4; -+ break; -+ -+ case FDT_END: -+ case FDT_END_NODE: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return FDT_END; -+ } -+ -+ if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) -+ return FDT_END; /* premature end */ -+ -+ *nextoffset = FDT_TAGALIGN(offset); -+ return tag; -+} -+ -+int fdt_check_node_offset_(const void *fdt, int offset) -+{ -+ if (!can_assume(VALID_INPUT) -+ && ((offset < 0) || (offset % FDT_TAGSIZE))) -+ return -FDT_ERR_BADOFFSET; -+ -+ if (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ -+ return offset; -+} -+ -+int fdt_check_prop_offset_(const void *fdt, int offset) -+{ -+ if (!can_assume(VALID_INPUT) -+ && ((offset < 0) || (offset % FDT_TAGSIZE))) -+ return -FDT_ERR_BADOFFSET; -+ -+ if (fdt_next_tag(fdt, offset, &offset) != FDT_PROP) -+ return -FDT_ERR_BADOFFSET; -+ -+ return offset; -+} -+ -+int fdt_next_node(const void *fdt, int offset, int *depth) -+{ -+ int nextoffset = 0; -+ uint32_t tag; -+ -+ if (offset >= 0) -+ if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) -+ return nextoffset; -+ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_PROP: -+ case FDT_NOP: -+ break; -+ -+ case FDT_BEGIN_NODE: -+ if (depth) -+ (*depth)++; -+ break; -+ -+ case FDT_END_NODE: -+ if (depth && ((--(*depth)) < 0)) -+ return nextoffset; -+ break; -+ -+ case FDT_END: -+ if ((nextoffset >= 0) -+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) -+ return -FDT_ERR_NOTFOUND; -+ else -+ return nextoffset; -+ } -+ } while (tag != FDT_BEGIN_NODE); -+ -+ return offset; -+} -+ -+int fdt_first_subnode(const void *fdt, int offset) -+{ -+ int depth = 0; -+ -+ offset = fdt_next_node(fdt, offset, &depth); -+ if (offset < 0 || depth != 1) -+ return -FDT_ERR_NOTFOUND; -+ -+ return offset; -+} -+ -+int fdt_next_subnode(const void *fdt, int offset) -+{ -+ int depth = 1; -+ -+ /* -+ * With respect to the parent, the depth of the next subnode will be -+ * the same as the last. -+ */ -+ do { -+ offset = fdt_next_node(fdt, offset, &depth); -+ if (offset < 0 || depth < 1) -+ return -FDT_ERR_NOTFOUND; -+ } while (depth > 1); -+ -+ return offset; -+} -+ -+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) -+{ -+ int len = strlen(s) + 1; -+ const char *last = strtab + tabsize - len; -+ const char *p; -+ -+ for (p = strtab; p <= last; p++) -+ if (memcmp(p, s, len) == 0) -+ return p; -+ return NULL; -+} -+ -+int fdt_move(const void *fdt, void *buf, int bufsize) -+{ -+ if (!can_assume(VALID_INPUT) && bufsize < 0) -+ return -FDT_ERR_NOSPACE; -+ -+ FDT_RO_PROBE(fdt); -+ -+ if (fdt_totalsize(fdt) > (unsigned int)bufsize) -+ return -FDT_ERR_NOSPACE; -+ -+ memmove(buf, fdt, fdt_totalsize(fdt)); -+ return 0; -+} -diff --git a/common/libfdt/fdt_addresses.c b/common/libfdt/fdt_addresses.c -new file mode 100644 -index 0000000..9a82cd0 ---- /dev/null -+++ b/common/libfdt/fdt_addresses.c -@@ -0,0 +1,101 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2014 David Gibson -+ * Copyright (C) 2018 embedded brains GmbH -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+static int fdt_cells(const void *fdt, int nodeoffset, const char *name) -+{ -+ const fdt32_t *c; -+ uint32_t val; -+ int len; -+ -+ c = fdt_getprop(fdt, nodeoffset, name, &len); -+ if (!c) -+ return len; -+ -+ if (len != sizeof(*c)) -+ return -FDT_ERR_BADNCELLS; -+ -+ val = fdt32_to_cpu(*c); -+ if (val > FDT_MAX_NCELLS) -+ return -FDT_ERR_BADNCELLS; -+ -+ return (int)val; -+} -+ -+int fdt_address_cells(const void *fdt, int nodeoffset) -+{ -+ int val; -+ -+ val = fdt_cells(fdt, nodeoffset, "#address-cells"); -+ if (val == 0) -+ return -FDT_ERR_BADNCELLS; -+ if (val == -FDT_ERR_NOTFOUND) -+ return 2; -+ return val; -+} -+ -+int fdt_size_cells(const void *fdt, int nodeoffset) -+{ -+ int val; -+ -+ val = fdt_cells(fdt, nodeoffset, "#size-cells"); -+ if (val == -FDT_ERR_NOTFOUND) -+ return 1; -+ return val; -+} -+ -+/* This function assumes that [address|size]_cells is 1 or 2 */ -+int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, -+ const char *name, uint64_t addr, uint64_t size) -+{ -+ int addr_cells, size_cells, ret; -+ uint8_t data[sizeof(fdt64_t) * 2], *prop; -+ -+ ret = fdt_address_cells(fdt, parent); -+ if (ret < 0) -+ return ret; -+ addr_cells = ret; -+ -+ ret = fdt_size_cells(fdt, parent); -+ if (ret < 0) -+ return ret; -+ size_cells = ret; -+ -+ /* check validity of address */ -+ prop = data; -+ if (addr_cells == 1) { -+ if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size)) -+ return -FDT_ERR_BADVALUE; -+ -+ fdt32_st(prop, (uint32_t)addr); -+ } else if (addr_cells == 2) { -+ fdt64_st(prop, addr); -+ } else { -+ return -FDT_ERR_BADNCELLS; -+ } -+ -+ /* check validity of size */ -+ prop += addr_cells * sizeof(fdt32_t); -+ if (size_cells == 1) { -+ if (size > UINT32_MAX) -+ return -FDT_ERR_BADVALUE; -+ -+ fdt32_st(prop, (uint32_t)size); -+ } else if (size_cells == 2) { -+ fdt64_st(prop, size); -+ } else { -+ return -FDT_ERR_BADNCELLS; -+ } -+ -+ return fdt_appendprop(fdt, nodeoffset, name, data, -+ (addr_cells + size_cells) * sizeof(fdt32_t)); -+} -diff --git a/common/libfdt/fdt_check.c b/common/libfdt/fdt_check.c -new file mode 100644 -index 0000000..fa410a8 ---- /dev/null -+++ b/common/libfdt/fdt_check.c -@@ -0,0 +1,93 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+int fdt_check_full(const void *fdt, size_t bufsize) -+{ -+ int err; -+ int num_memrsv; -+ int offset, nextoffset = 0; -+ uint32_t tag; -+ unsigned int depth = 0; -+ const void *prop; -+ const char *propname; -+ bool expect_end = false; -+ -+ if (bufsize < FDT_V1_SIZE) -+ return -FDT_ERR_TRUNCATED; -+ if (bufsize < fdt_header_size(fdt)) -+ return -FDT_ERR_TRUNCATED; -+ err = fdt_check_header(fdt); -+ if (err != 0) -+ return err; -+ if (bufsize < fdt_totalsize(fdt)) -+ return -FDT_ERR_TRUNCATED; -+ -+ num_memrsv = fdt_num_mem_rsv(fdt); -+ if (num_memrsv < 0) -+ return num_memrsv; -+ -+ while (1) { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ if (nextoffset < 0) -+ return nextoffset; -+ -+ /* If we see two root nodes, something is wrong */ -+ if (expect_end && tag != FDT_END) -+ return -FDT_ERR_BADSTRUCTURE; -+ -+ switch (tag) { -+ case FDT_NOP: -+ break; -+ -+ case FDT_END: -+ if (depth != 0) -+ return -FDT_ERR_BADSTRUCTURE; -+ return 0; -+ -+ case FDT_BEGIN_NODE: -+ depth++; -+ if (depth > INT_MAX) -+ return -FDT_ERR_BADSTRUCTURE; -+ -+ /* The root node must have an empty name */ -+ if (depth == 1) { -+ const char *name; -+ int len; -+ -+ name = fdt_get_name(fdt, offset, &len); -+ if (*name || len) -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ break; -+ -+ case FDT_END_NODE: -+ if (depth == 0) -+ return -FDT_ERR_BADSTRUCTURE; -+ depth--; -+ if (depth == 0) -+ expect_end = true; -+ break; -+ -+ case FDT_PROP: -+ prop = fdt_getprop_by_offset(fdt, offset, &propname, -+ &err); -+ if (!prop) -+ return err; -+ break; -+ -+ default: -+ return -FDT_ERR_INTERNAL; -+ } -+ } -+} -diff --git a/common/libfdt/fdt_empty_tree.c b/common/libfdt/fdt_empty_tree.c -new file mode 100644 -index 0000000..49d54d4 ---- /dev/null -+++ b/common/libfdt/fdt_empty_tree.c -@@ -0,0 +1,38 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2012 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+int fdt_create_empty_tree(void *buf, int bufsize) -+{ -+ int err; -+ -+ err = fdt_create(buf, bufsize); -+ if (err) -+ return err; -+ -+ err = fdt_finish_reservemap(buf); -+ if (err) -+ return err; -+ -+ err = fdt_begin_node(buf, ""); -+ if (err) -+ return err; -+ -+ err = fdt_end_node(buf); -+ if (err) -+ return err; -+ -+ err = fdt_finish(buf); -+ if (err) -+ return err; -+ -+ return fdt_open_into(buf, buf, bufsize); -+} -diff --git a/common/libfdt/fdt_overlay.c b/common/libfdt/fdt_overlay.c -new file mode 100644 -index 0000000..d217e79 ---- /dev/null -+++ b/common/libfdt/fdt_overlay.c -@@ -0,0 +1,882 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2016 Free Electrons -+ * Copyright (C) 2016 NextThing Co. -+ */ -+#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 targeting is -+ * done (through a phandle or a path) -+ * -+ * returns: -+ * the targeted 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; -+ fixup_len /= sizeof(uint32_t); -+ -+ 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; 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_RO_PROBE(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; -+ -+ if (*path != '/') -+ return -FDT_ERR_BADVALUE; -+ -+ /* get fragment name first */ -+ s = strchr(path + 1, '/'); -+ if (!s) { -+ /* Symbol refers to something that won't end -+ * up in the target tree */ -+ continue; -+ } -+ -+ 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) == 0)) { -+ /* //__overlay__/ */ -+ rel_path = s + len; -+ rel_path_len = e - rel_path - 1; -+ } else if ((e - s) == len -+ && (memcmp(s, "/__overlay__", len - 1) == 0)) { -+ /* //__overlay__ */ -+ rel_path = ""; -+ rel_path_len = 0; -+ } else { -+ /* Symbol refers to something that won't end -+ * up in the target tree */ -+ continue; -+ } -+ -+ /* 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; -+ int ret; -+ -+ FDT_RO_PROBE(fdt); -+ FDT_RO_PROBE(fdto); -+ -+ ret = fdt_find_max_phandle(fdt, &delta); -+ if (ret) -+ goto err; -+ -+ 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/common/libfdt/fdt_ro.c b/common/libfdt/fdt_ro.c -new file mode 100644 -index 0000000..17584da ---- /dev/null -+++ b/common/libfdt/fdt_ro.c -@@ -0,0 +1,859 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+static int fdt_nodename_eq_(const void *fdt, int offset, -+ const char *s, int len) -+{ -+ int olen; -+ const char *p = fdt_get_name(fdt, offset, &olen); -+ -+ if (!p || olen < len) -+ /* short match */ -+ return 0; -+ -+ if (memcmp(p, s, len) != 0) -+ return 0; -+ -+ if (p[len] == '\0') -+ return 1; -+ else if (!memchr(s, '@', len) && (p[len] == '@')) -+ return 1; -+ else -+ return 0; -+} -+ -+const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) -+{ -+ int32_t totalsize; -+ uint32_t absoffset; -+ size_t len; -+ int err; -+ const char *s, *n; -+ -+ if (can_assume(VALID_INPUT)) { -+ s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -+ -+ if (lenp) -+ *lenp = strlen(s); -+ return s; -+ } -+ totalsize = fdt_ro_probe_(fdt); -+ err = totalsize; -+ if (totalsize < 0) -+ goto fail; -+ -+ err = -FDT_ERR_BADOFFSET; -+ absoffset = stroffset + fdt_off_dt_strings(fdt); -+ if (absoffset >= (unsigned)totalsize) -+ goto fail; -+ len = totalsize - absoffset; -+ -+ if (fdt_magic(fdt) == FDT_MAGIC) { -+ if (stroffset < 0) -+ goto fail; -+ if (can_assume(LATEST) || fdt_version(fdt) >= 17) { -+ if ((unsigned)stroffset >= fdt_size_dt_strings(fdt)) -+ goto fail; -+ if ((fdt_size_dt_strings(fdt) - stroffset) < len) -+ len = fdt_size_dt_strings(fdt) - stroffset; -+ } -+ } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { -+ unsigned int sw_stroffset = -stroffset; -+ -+ if ((stroffset >= 0) || -+ (sw_stroffset > fdt_size_dt_strings(fdt))) -+ goto fail; -+ if (sw_stroffset < len) -+ len = sw_stroffset; -+ } else { -+ err = -FDT_ERR_INTERNAL; -+ goto fail; -+ } -+ -+ s = (const char *)fdt + absoffset; -+ n = memchr(s, '\0', len); -+ if (!n) { -+ /* missing terminating NULL */ -+ err = -FDT_ERR_TRUNCATED; -+ goto fail; -+ } -+ -+ if (lenp) -+ *lenp = n - s; -+ return s; -+ -+fail: -+ if (lenp) -+ *lenp = err; -+ return NULL; -+} -+ -+const char *fdt_string(const void *fdt, int stroffset) -+{ -+ return fdt_get_string(fdt, stroffset, NULL); -+} -+ -+static int fdt_string_eq_(const void *fdt, int stroffset, -+ const char *s, int len) -+{ -+ int slen; -+ const char *p = fdt_get_string(fdt, stroffset, &slen); -+ -+ return p && (slen == len) && (memcmp(p, s, len) == 0); -+} -+ -+int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) -+{ -+ uint32_t max = 0; -+ int offset = -1; -+ -+ while (true) { -+ uint32_t value; -+ -+ offset = fdt_next_node(fdt, offset, NULL); -+ if (offset < 0) { -+ if (offset == -FDT_ERR_NOTFOUND) -+ break; -+ -+ return offset; -+ } -+ -+ value = fdt_get_phandle(fdt, offset); -+ -+ if (value > max) -+ max = value; -+ } -+ -+ if (phandle) -+ *phandle = max; -+ -+ return 0; -+} -+ -+int fdt_generate_phandle(const void *fdt, uint32_t *phandle) -+{ -+ uint32_t max; -+ int err; -+ -+ err = fdt_find_max_phandle(fdt, &max); -+ if (err < 0) -+ return err; -+ -+ if (max == FDT_MAX_PHANDLE) -+ return -FDT_ERR_NOPHANDLES; -+ -+ if (phandle) -+ *phandle = max + 1; -+ -+ return 0; -+} -+ -+static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) -+{ -+ unsigned int offset = n * sizeof(struct fdt_reserve_entry); -+ unsigned int absoffset = fdt_off_mem_rsvmap(fdt) + offset; -+ -+ if (!can_assume(VALID_INPUT)) { -+ if (absoffset < fdt_off_mem_rsvmap(fdt)) -+ return NULL; -+ if (absoffset > fdt_totalsize(fdt) - -+ sizeof(struct fdt_reserve_entry)) -+ return NULL; -+ } -+ return fdt_mem_rsv_(fdt, n); -+} -+ -+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) -+{ -+ const struct fdt_reserve_entry *re; -+ -+ FDT_RO_PROBE(fdt); -+ re = fdt_mem_rsv(fdt, n); -+ if (!can_assume(VALID_INPUT) && !re) -+ return -FDT_ERR_BADOFFSET; -+ -+ *address = fdt64_ld_(&re->address); -+ *size = fdt64_ld_(&re->size); -+ return 0; -+} -+ -+int fdt_num_mem_rsv(const void *fdt) -+{ -+ int i; -+ const struct fdt_reserve_entry *re; -+ -+ for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { -+ if (fdt64_ld_(&re->size) == 0) -+ return i; -+ } -+ return -FDT_ERR_TRUNCATED; -+} -+ -+static int nextprop_(const void *fdt, int offset) -+{ -+ uint32_t tag; -+ int nextoffset; -+ -+ do { -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_END: -+ if (nextoffset >= 0) -+ return -FDT_ERR_BADSTRUCTURE; -+ else -+ return nextoffset; -+ -+ case FDT_PROP: -+ return offset; -+ } -+ offset = nextoffset; -+ } while (tag == FDT_NOP); -+ -+ return -FDT_ERR_NOTFOUND; -+} -+ -+int fdt_subnode_offset_namelen(const void *fdt, int offset, -+ const char *name, int namelen) -+{ -+ int depth; -+ -+ FDT_RO_PROBE(fdt); -+ -+ for (depth = 0; -+ (offset >= 0) && (depth >= 0); -+ offset = fdt_next_node(fdt, offset, &depth)) -+ if ((depth == 1) -+ && fdt_nodename_eq_(fdt, offset, name, namelen)) -+ return offset; -+ -+ if (depth < 0) -+ return -FDT_ERR_NOTFOUND; -+ return offset; /* error */ -+} -+ -+int fdt_subnode_offset(const void *fdt, int parentoffset, -+ const char *name) -+{ -+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); -+} -+ -+int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) -+{ -+ const char *end = path + namelen; -+ const char *p = path; -+ int offset = 0; -+ -+ FDT_RO_PROBE(fdt); -+ -+ /* see if we have an alias */ -+ if (*path != '/') { -+ const char *q = memchr(path, '/', end - p); -+ -+ if (!q) -+ q = end; -+ -+ p = fdt_get_alias_namelen(fdt, p, q - p); -+ if (!p) -+ return -FDT_ERR_BADPATH; -+ offset = fdt_path_offset(fdt, p); -+ -+ p = q; -+ } -+ -+ while (p < end) { -+ const char *q; -+ -+ while (*p == '/') { -+ p++; -+ if (p == end) -+ return offset; -+ } -+ q = memchr(p, '/', end - p); -+ if (! q) -+ q = end; -+ -+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); -+ if (offset < 0) -+ return offset; -+ -+ p = q; -+ } -+ -+ 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 char *nameptr; -+ int err; -+ -+ if (((err = fdt_ro_probe_(fdt)) < 0) -+ || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) -+ goto fail; -+ -+ nameptr = nh->name; -+ -+ if (!can_assume(LATEST) && 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(nameptr); -+ -+ return nameptr; -+ -+ fail: -+ if (len) -+ *len = err; -+ return NULL; -+} -+ -+int fdt_first_property_offset(const void *fdt, int nodeoffset) -+{ -+ int offset; -+ -+ if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) -+ return offset; -+ -+ return nextprop_(fdt, offset); -+} -+ -+int fdt_next_property_offset(const void *fdt, int offset) -+{ -+ if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) -+ return offset; -+ -+ return nextprop_(fdt, offset); -+} -+ -+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 (!can_assume(VALID_INPUT) && -+ (err = fdt_check_prop_offset_(fdt, offset)) < 0) { -+ if (lenp) -+ *lenp = err; -+ return NULL; -+ } -+ -+ prop = fdt_offset_ptr_(fdt, offset); -+ -+ if (lenp) -+ *lenp = fdt32_ld_(&prop->len); -+ -+ return prop; -+} -+ -+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 (!can_assume(LATEST) && 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; -+ -+ prop = fdt_get_property_by_offset_(fdt, offset, lenp); -+ if (!can_assume(LIBFDT_FLAWLESS) && !prop) { -+ offset = -FDT_ERR_INTERNAL; -+ break; -+ } -+ if (fdt_string_eq_(fdt, fdt32_ld_(&prop->nameoff), -+ name, namelen)) { -+ if (poffset) -+ *poffset = offset; -+ return prop; -+ } -+ } -+ -+ if (lenp) -+ *lenp = offset; -+ 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 (!can_assume(LATEST) && 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) -+{ -+ return fdt_get_property_namelen(fdt, nodeoffset, name, -+ strlen(name), lenp); -+} -+ -+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, -+ &poffset); -+ if (!prop) -+ return NULL; -+ -+ /* Handle realignment */ -+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && -+ (poffset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8) -+ return prop->data + 4; -+ return prop->data; -+} -+ -+const void *fdt_getprop_by_offset(const void *fdt, int offset, -+ const char **namep, int *lenp) -+{ -+ const struct fdt_property *prop; -+ -+ prop = fdt_get_property_by_offset_(fdt, offset, lenp); -+ if (!prop) -+ return NULL; -+ if (namep) { -+ const char *name; -+ int namelen; -+ -+ if (!can_assume(VALID_INPUT)) { -+ name = fdt_get_string(fdt, fdt32_ld_(&prop->nameoff), -+ &namelen); -+ if (!name) { -+ if (lenp) -+ *lenp = namelen; -+ return NULL; -+ } -+ *namep = name; -+ } else { -+ *namep = fdt_string(fdt, fdt32_ld_(&prop->nameoff)); -+ } -+ } -+ -+ /* Handle realignment */ -+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && -+ (offset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8) -+ return prop->data + 4; -+ return prop->data; -+} -+ -+const void *fdt_getprop(const void *fdt, int nodeoffset, -+ const char *name, int *lenp) -+{ -+ return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); -+} -+ -+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) -+{ -+ const fdt32_t *php; -+ int len; -+ -+ /* FIXME: This is a bit sub-optimal, since we potentially scan -+ * over all the properties twice. */ -+ php = fdt_getprop(fdt, nodeoffset, "phandle", &len); -+ if (!php || (len != sizeof(*php))) { -+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); -+ if (!php || (len != sizeof(*php))) -+ return 0; -+ } -+ -+ return fdt32_ld_(php); -+} -+ -+const char *fdt_get_alias_namelen(const void *fdt, -+ const char *name, int namelen) -+{ -+ int aliasoffset; -+ -+ aliasoffset = fdt_path_offset(fdt, "/aliases"); -+ if (aliasoffset < 0) -+ return NULL; -+ -+ return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); -+} -+ -+const char *fdt_get_alias(const void *fdt, const char *name) -+{ -+ return fdt_get_alias_namelen(fdt, name, strlen(name)); -+} -+ -+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) -+{ -+ int pdepth = 0, p = 0; -+ int offset, depth, namelen; -+ const char *name; -+ -+ FDT_RO_PROBE(fdt); -+ -+ if (buflen < 2) -+ return -FDT_ERR_NOSPACE; -+ -+ for (offset = 0, depth = 0; -+ (offset >= 0) && (offset <= nodeoffset); -+ offset = fdt_next_node(fdt, offset, &depth)) { -+ while (pdepth > depth) { -+ do { -+ p--; -+ } while (buf[p-1] != '/'); -+ pdepth--; -+ } -+ -+ if (pdepth >= depth) { -+ name = fdt_get_name(fdt, offset, &namelen); -+ if (!name) -+ return namelen; -+ if ((p + namelen + 1) <= buflen) { -+ memcpy(buf + p, name, namelen); -+ p += namelen; -+ buf[p++] = '/'; -+ pdepth++; -+ } -+ } -+ -+ if (offset == nodeoffset) { -+ if (pdepth < (depth + 1)) -+ return -FDT_ERR_NOSPACE; -+ -+ if (p > 1) /* special case so that root path is "/", not "" */ -+ p--; -+ buf[p] = '\0'; -+ return 0; -+ } -+ } -+ -+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) -+ return -FDT_ERR_BADOFFSET; -+ else if (offset == -FDT_ERR_BADOFFSET) -+ return -FDT_ERR_BADSTRUCTURE; -+ -+ return offset; /* error from fdt_next_node() */ -+} -+ -+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, -+ int supernodedepth, int *nodedepth) -+{ -+ int offset, depth; -+ int supernodeoffset = -FDT_ERR_INTERNAL; -+ -+ FDT_RO_PROBE(fdt); -+ -+ if (supernodedepth < 0) -+ return -FDT_ERR_NOTFOUND; -+ -+ for (offset = 0, depth = 0; -+ (offset >= 0) && (offset <= nodeoffset); -+ offset = fdt_next_node(fdt, offset, &depth)) { -+ if (depth == supernodedepth) -+ supernodeoffset = offset; -+ -+ if (offset == nodeoffset) { -+ if (nodedepth) -+ *nodedepth = depth; -+ -+ if (supernodedepth > depth) -+ return -FDT_ERR_NOTFOUND; -+ else -+ return supernodeoffset; -+ } -+ } -+ -+ if (!can_assume(VALID_INPUT)) { -+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) -+ return -FDT_ERR_BADOFFSET; -+ else if (offset == -FDT_ERR_BADOFFSET) -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ -+ return offset; /* error from fdt_next_node() */ -+} -+ -+int fdt_node_depth(const void *fdt, int nodeoffset) -+{ -+ int nodedepth; -+ int err; -+ -+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); -+ if (err) -+ return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err : -+ -FDT_ERR_INTERNAL; -+ return nodedepth; -+} -+ -+int fdt_parent_offset(const void *fdt, int nodeoffset) -+{ -+ int nodedepth = fdt_node_depth(fdt, nodeoffset); -+ -+ if (nodedepth < 0) -+ return nodedepth; -+ return fdt_supernode_atdepth_offset(fdt, nodeoffset, -+ nodedepth - 1, NULL); -+} -+ -+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, -+ const char *propname, -+ const void *propval, int proplen) -+{ -+ int offset; -+ const void *val; -+ int len; -+ -+ FDT_RO_PROBE(fdt); -+ -+ /* FIXME: The algorithm here is pretty horrible: we scan each -+ * property of a node in fdt_getprop(), then if that didn't -+ * find what we want, we scan over them again making our way -+ * to the next node. Still it's the easiest to implement -+ * approach; performance can come later. */ -+ for (offset = fdt_next_node(fdt, startoffset, NULL); -+ offset >= 0; -+ offset = fdt_next_node(fdt, offset, NULL)) { -+ val = fdt_getprop(fdt, offset, propname, &len); -+ if (val && (len == proplen) -+ && (memcmp(val, propval, len) == 0)) -+ return offset; -+ } -+ -+ return offset; /* error from fdt_next_node() */ -+} -+ -+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) -+{ -+ int offset; -+ -+ if ((phandle == 0) || (phandle == ~0U)) -+ return -FDT_ERR_BADPHANDLE; -+ -+ FDT_RO_PROBE(fdt); -+ -+ /* FIXME: The algorithm here is pretty horrible: we -+ * potentially scan each property of a node in -+ * fdt_get_phandle(), then if that didn't find what -+ * we want, we scan over them again making our way to the next -+ * node. Still it's the easiest to implement approach; -+ * performance can come later. */ -+ for (offset = fdt_next_node(fdt, -1, NULL); -+ offset >= 0; -+ offset = fdt_next_node(fdt, offset, NULL)) { -+ if (fdt_get_phandle(fdt, offset) == phandle) -+ return offset; -+ } -+ -+ return offset; /* error from fdt_next_node() */ -+} -+ -+int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) -+{ -+ int len = strlen(str); -+ const char *p; -+ -+ while (listlen >= len) { -+ if (memcmp(str, strlist, len+1) == 0) -+ return 1; -+ p = memchr(strlist, '\0', listlen); -+ if (!p) -+ return 0; /* malformed strlist.. */ -+ listlen -= (p-strlist) + 1; -+ strlist = p + 1; -+ } -+ 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) -+{ -+ const void *prop; -+ int len; -+ -+ prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); -+ if (!prop) -+ return len; -+ -+ return !fdt_stringlist_contains(prop, len, compatible); -+} -+ -+int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -+ const char *compatible) -+{ -+ int offset, err; -+ -+ FDT_RO_PROBE(fdt); -+ -+ /* FIXME: The algorithm here is pretty horrible: we scan each -+ * property of a node in fdt_node_check_compatible(), then if -+ * that didn't find what we want, we scan over them again -+ * making our way to the next node. Still it's the easiest to -+ * implement approach; performance can come later. */ -+ for (offset = fdt_next_node(fdt, startoffset, NULL); -+ offset >= 0; -+ offset = fdt_next_node(fdt, offset, NULL)) { -+ err = fdt_node_check_compatible(fdt, offset, compatible); -+ if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) -+ return err; -+ else if (err == 0) -+ return offset; -+ } -+ -+ return offset; /* error from fdt_next_node() */ -+} -diff --git a/common/libfdt/fdt_rw.c b/common/libfdt/fdt_rw.c -new file mode 100644 -index 0000000..3621d36 ---- /dev/null -+++ b/common/libfdt/fdt_rw.c -@@ -0,0 +1,500 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+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) < -+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) -+ || (fdt_off_dt_strings(fdt) < -+ (fdt_off_dt_struct(fdt) + struct_size)) -+ || (fdt_totalsize(fdt) < -+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); -+} -+ -+static int fdt_rw_probe_(void *fdt) -+{ -+ if (can_assume(VALID_DTB)) -+ return 0; -+ FDT_RO_PROBE(fdt); -+ -+ if (!can_assume(LATEST) && fdt_version(fdt) < 17) -+ return -FDT_ERR_BADVERSION; -+ if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), -+ fdt_size_dt_struct(fdt))) -+ return -FDT_ERR_BADLAYOUT; -+ if (!can_assume(LATEST) && fdt_version(fdt) > 17) -+ fdt_set_version(fdt, 17); -+ -+ return 0; -+} -+ -+#define FDT_RW_PROBE(fdt) \ -+ { \ -+ int err_; \ -+ if ((err_ = fdt_rw_probe_(fdt)) != 0) \ -+ return err_; \ -+ } -+ -+static inline unsigned 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) -+{ -+ char *p = splicepoint; -+ unsigned int dsize = fdt_data_size_(fdt); -+ size_t soff = p - (char *)fdt; -+ -+ if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize)) -+ return -FDT_ERR_BADOFFSET; -+ if ((p < (char *)fdt) || (dsize + newlen < (unsigned)oldlen)) -+ return -FDT_ERR_BADOFFSET; -+ if (dsize - oldlen + newlen > fdt_totalsize(fdt)) -+ return -FDT_ERR_NOSPACE; -+ memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen)); -+ return 0; -+} -+ -+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)); -+ if (err) -+ return err; -+ fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); -+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); -+ return 0; -+} -+ -+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))) -+ return err; -+ -+ fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); -+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); -+ return 0; -+} -+ -+/* Must only be used to roll back in case of error */ -+static void fdt_del_last_string_(void *fdt, const char *s) -+{ -+ int newlen = strlen(s) + 1; -+ -+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - 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))) -+ return err; -+ -+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); -+ return 0; -+} -+ -+/** -+ * fdt_find_add_string_() - Find or allocate a string -+ * -+ * @fdt: pointer to the device tree to check/adjust -+ * @s: string to find/add -+ * @allocated: Set to 0 if the string was found, 1 if not found and so -+ * allocated. Ignored if can_assume(NO_ROLLBACK) -+ * @return offset of string in the string table (whether found or added) -+ */ -+static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) -+{ -+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); -+ const char *p; -+ char *new; -+ int len = strlen(s) + 1; -+ int err; -+ -+ if (!can_assume(NO_ROLLBACK)) -+ *allocated = 0; -+ -+ 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); -+ if (err) -+ return err; -+ -+ if (!can_assume(NO_ROLLBACK)) -+ *allocated = 1; -+ -+ memcpy(new, s, len); -+ return (new - strtab); -+} -+ -+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) -+{ -+ struct fdt_reserve_entry *re; -+ int err; -+ -+ FDT_RW_PROBE(fdt); -+ -+ re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); -+ err = fdt_splice_mem_rsv_(fdt, re, 0, 1); -+ if (err) -+ return err; -+ -+ re->address = cpu_to_fdt64(address); -+ re->size = cpu_to_fdt64(size); -+ return 0; -+} -+ -+int fdt_del_mem_rsv(void *fdt, int n) -+{ -+ struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); -+ -+ FDT_RW_PROBE(fdt); -+ -+ if (n >= fdt_num_mem_rsv(fdt)) -+ return -FDT_ERR_NOTFOUND; -+ -+ return fdt_splice_mem_rsv_(fdt, re, 1, 0); -+} -+ -+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) -+ return oldlen; -+ -+ if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), -+ FDT_TAGALIGN(len)))) -+ return err; -+ -+ (*prop)->len = cpu_to_fdt32(len); -+ return 0; -+} -+ -+static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, -+ int len, struct fdt_property **prop) -+{ -+ int proplen; -+ int nextoffset; -+ int namestroff; -+ int err; -+ int allocated; -+ -+ if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) -+ return nextoffset; -+ -+ namestroff = fdt_find_add_string_(fdt, name, &allocated); -+ if (namestroff < 0) -+ return namestroff; -+ -+ *prop = fdt_offset_ptr_w_(fdt, nextoffset); -+ proplen = sizeof(**prop) + FDT_TAGALIGN(len); -+ -+ err = fdt_splice_struct_(fdt, *prop, 0, proplen); -+ if (err) { -+ /* Delete the string if we failed to add it */ -+ if (!can_assume(NO_ROLLBACK) && allocated) -+ fdt_del_last_string_(fdt, name); -+ return err; -+ } -+ -+ (*prop)->tag = cpu_to_fdt32(FDT_PROP); -+ (*prop)->nameoff = cpu_to_fdt32(namestroff); -+ (*prop)->len = cpu_to_fdt32(len); -+ return 0; -+} -+ -+int fdt_set_name(void *fdt, int nodeoffset, const char *name) -+{ -+ char *namep; -+ int oldlen, newlen; -+ int err; -+ -+ FDT_RW_PROBE(fdt); -+ -+ namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); -+ if (!namep) -+ return oldlen; -+ -+ newlen = strlen(name); -+ -+ err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), -+ FDT_TAGALIGN(newlen+1)); -+ if (err) -+ return err; -+ -+ memcpy(namep, name, newlen+1); -+ return 0; -+} -+ -+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, -+ int len, void **prop_data) -+{ -+ struct fdt_property *prop; -+ int err; -+ -+ FDT_RW_PROBE(fdt); -+ -+ err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); -+ if (err == -FDT_ERR_NOTFOUND) -+ 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; -+ -+ if (len) -+ memcpy(prop_data, val, len); -+ return 0; -+} -+ -+int fdt_appendprop(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len) -+{ -+ struct fdt_property *prop; -+ int err, oldlen, newlen; -+ -+ FDT_RW_PROBE(fdt); -+ -+ prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); -+ if (prop) { -+ newlen = len + oldlen; -+ err = fdt_splice_struct_(fdt, prop->data, -+ FDT_TAGALIGN(oldlen), -+ FDT_TAGALIGN(newlen)); -+ if (err) -+ return err; -+ prop->len = cpu_to_fdt32(newlen); -+ memcpy(prop->data + oldlen, val, len); -+ } else { -+ err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); -+ if (err) -+ return err; -+ memcpy(prop->data, val, len); -+ } -+ return 0; -+} -+ -+int fdt_delprop(void *fdt, int nodeoffset, const char *name) -+{ -+ struct fdt_property *prop; -+ int len, proplen; -+ -+ FDT_RW_PROBE(fdt); -+ -+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -+ if (!prop) -+ return len; -+ -+ proplen = sizeof(*prop) + FDT_TAGALIGN(len); -+ return fdt_splice_struct_(fdt, prop, proplen, 0); -+} -+ -+int fdt_add_subnode_namelen(void *fdt, int parentoffset, -+ const char *name, int namelen) -+{ -+ struct fdt_node_header *nh; -+ int offset, nextoffset; -+ int nodelen; -+ int err; -+ uint32_t tag; -+ fdt32_t *endtag; -+ -+ FDT_RW_PROBE(fdt); -+ -+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); -+ if (offset >= 0) -+ return -FDT_ERR_EXISTS; -+ else if (offset != -FDT_ERR_NOTFOUND) -+ return offset; -+ -+ /* Try to place the new node after the parent's properties */ -+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset); -+ /* the fdt_subnode_offset_namelen() should ensure this never hits */ -+ if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE)) -+ return -FDT_ERR_INTERNAL; -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ } while ((tag == FDT_PROP) || (tag == FDT_NOP)); -+ -+ nh = fdt_offset_ptr_w_(fdt, offset); -+ nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; -+ -+ err = fdt_splice_struct_(fdt, nh, 0, nodelen); -+ if (err) -+ return err; -+ -+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); -+ memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); -+ memcpy(nh->name, name, namelen); -+ endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE); -+ *endtag = cpu_to_fdt32(FDT_END_NODE); -+ -+ return offset; -+} -+ -+int fdt_add_subnode(void *fdt, int parentoffset, const char *name) -+{ -+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); -+} -+ -+int fdt_del_node(void *fdt, int nodeoffset) -+{ -+ int endoffset; -+ -+ FDT_RW_PROBE(fdt); -+ -+ endoffset = fdt_node_end_offset_(fdt, nodeoffset); -+ if (endoffset < 0) -+ return endoffset; -+ -+ return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), -+ endoffset - nodeoffset, 0); -+} -+ -+static void fdt_packblocks_(const char *old, char *new, -+ int mem_rsv_size, -+ int struct_size, -+ int strings_size) -+{ -+ int mem_rsv_off, struct_off, strings_off; -+ -+ mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); -+ struct_off = mem_rsv_off + mem_rsv_size; -+ strings_off = struct_off + struct_size; -+ -+ memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); -+ fdt_set_off_mem_rsvmap(new, mem_rsv_off); -+ -+ memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); -+ fdt_set_off_dt_struct(new, struct_off); -+ fdt_set_size_dt_struct(new, struct_size); -+ -+ memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size); -+ fdt_set_off_dt_strings(new, strings_off); -+ fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); -+} -+ -+int fdt_open_into(const void *fdt, void *buf, int bufsize) -+{ -+ int err; -+ int mem_rsv_size, struct_size; -+ int newsize; -+ const char *fdtstart = fdt; -+ const char *fdtend = fdtstart + fdt_totalsize(fdt); -+ char *tmp; -+ -+ FDT_RO_PROBE(fdt); -+ -+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) -+ * sizeof(struct fdt_reserve_entry); -+ -+ if (can_assume(LATEST) || fdt_version(fdt) >= 17) { -+ struct_size = fdt_size_dt_struct(fdt); -+ } else if (fdt_version(fdt) == 16) { -+ struct_size = 0; -+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) -+ ; -+ if (struct_size < 0) -+ return struct_size; -+ } else { -+ return -FDT_ERR_BADVERSION; -+ } -+ -+ if (can_assume(LIBFDT_ORDER) || -+ !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { -+ /* no further work necessary */ -+ err = fdt_move(fdt, buf, bufsize); -+ if (err) -+ return err; -+ fdt_set_version(buf, 17); -+ fdt_set_size_dt_struct(buf, struct_size); -+ fdt_set_totalsize(buf, bufsize); -+ return 0; -+ } -+ -+ /* Need to reorder */ -+ newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size -+ + struct_size + fdt_size_dt_strings(fdt); -+ -+ if (bufsize < newsize) -+ return -FDT_ERR_NOSPACE; -+ -+ /* First attempt to build converted tree at beginning of buffer */ -+ tmp = buf; -+ /* But if that overlaps with the old tree... */ -+ if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { -+ /* Try right after the old tree instead */ -+ tmp = (char *)(uintptr_t)fdtend; -+ if ((tmp + newsize) > ((char *)buf + bufsize)) -+ return -FDT_ERR_NOSPACE; -+ } -+ -+ fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size, -+ fdt_size_dt_strings(fdt)); -+ memmove(buf, tmp, newsize); -+ -+ fdt_set_magic(buf, FDT_MAGIC); -+ fdt_set_totalsize(buf, bufsize); -+ fdt_set_version(buf, 17); -+ fdt_set_last_comp_version(buf, 16); -+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); -+ -+ return 0; -+} -+ -+int fdt_pack(void *fdt) -+{ -+ int mem_rsv_size; -+ -+ FDT_RW_PROBE(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_size_dt_strings(fdt)); -+ fdt_set_totalsize(fdt, fdt_data_size_(fdt)); -+ -+ return 0; -+} -diff --git a/common/libfdt/fdt_strerror.c b/common/libfdt/fdt_strerror.c -new file mode 100644 -index 0000000..b435693 ---- /dev/null -+++ b/common/libfdt/fdt_strerror.c -@@ -0,0 +1,59 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+struct fdt_errtabent { -+ const char *str; -+}; -+ -+#define FDT_ERRTABENT(val) \ -+ [(val)] = { .str = #val, } -+ -+static struct fdt_errtabent fdt_errtable[] = { -+ FDT_ERRTABENT(FDT_ERR_NOTFOUND), -+ FDT_ERRTABENT(FDT_ERR_EXISTS), -+ FDT_ERRTABENT(FDT_ERR_NOSPACE), -+ -+ 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), -+ FDT_ERRTABENT(FDT_ERR_BADMAGIC), -+ 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), -+ FDT_ERRTABENT(FDT_ERR_BADFLAGS), -+}; -+#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) -+ -+const char *fdt_strerror(int errval) -+{ -+ if (errval > 0) -+ return ""; -+ else if (errval == 0) -+ return ""; -+ else if (-errval < FDT_ERRTABSIZE) { -+ const char *s = fdt_errtable[-errval].str; -+ -+ if (s) -+ return s; -+ } -+ -+ return ""; -+} -diff --git a/common/libfdt/fdt_sw.c b/common/libfdt/fdt_sw.c -new file mode 100644 -index 0000000..4c569ee ---- /dev/null -+++ b/common/libfdt/fdt_sw.c -@@ -0,0 +1,384 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+static int fdt_sw_probe_(void *fdt) -+{ -+ if (!can_assume(VALID_INPUT)) { -+ if (fdt_magic(fdt) == FDT_MAGIC) -+ return -FDT_ERR_BADSTATE; -+ else if (fdt_magic(fdt) != FDT_SW_MAGIC) -+ return -FDT_ERR_BADMAGIC; -+ } -+ -+ return 0; -+} -+ -+#define FDT_SW_PROBE(fdt) \ -+ { \ -+ int err; \ -+ if ((err = fdt_sw_probe_(fdt)) != 0) \ -+ return err; \ -+ } -+ -+/* 'memrsv' state: Initial state after fdt_create() -+ * -+ * Allowed functions: -+ * fdt_add_reservemap_entry() -+ * fdt_finish_reservemap() [moves to 'struct' state] -+ */ -+static int fdt_sw_probe_memrsv_(void *fdt) -+{ -+ int err = fdt_sw_probe_(fdt); -+ if (err) -+ return err; -+ -+ if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0) -+ return -FDT_ERR_BADSTATE; -+ return 0; -+} -+ -+#define FDT_SW_PROBE_MEMRSV(fdt) \ -+ { \ -+ int err; \ -+ if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \ -+ return err; \ -+ } -+ -+/* 'struct' state: Enter this state after fdt_finish_reservemap() -+ * -+ * Allowed functions: -+ * fdt_begin_node() -+ * fdt_end_node() -+ * fdt_property*() -+ * fdt_finish() [moves to 'complete' state] -+ */ -+static int fdt_sw_probe_struct_(void *fdt) -+{ -+ int err = fdt_sw_probe_(fdt); -+ if (err) -+ return err; -+ -+ if (!can_assume(VALID_INPUT) && -+ fdt_off_dt_strings(fdt) != fdt_totalsize(fdt)) -+ return -FDT_ERR_BADSTATE; -+ return 0; -+} -+ -+#define FDT_SW_PROBE_STRUCT(fdt) \ -+ { \ -+ int err; \ -+ if ((err = fdt_sw_probe_struct_(fdt)) != 0) \ -+ return err; \ -+ } -+ -+static inline uint32_t sw_flags(void *fdt) -+{ -+ /* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */ -+ return fdt_last_comp_version(fdt); -+} -+ -+/* 'complete' state: Enter this state after fdt_finish() -+ * -+ * Allowed functions: none -+ */ -+ -+static void *fdt_grab_space_(void *fdt, size_t len) -+{ -+ unsigned int offset = fdt_size_dt_struct(fdt); -+ unsigned int spaceleft; -+ -+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) -+ - fdt_size_dt_strings(fdt); -+ -+ if ((offset + len < offset) || (offset + len > spaceleft)) -+ return NULL; -+ -+ fdt_set_size_dt_struct(fdt, offset + len); -+ return fdt_offset_ptr_w_(fdt, offset); -+} -+ -+int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) -+{ -+ const int hdrsize = FDT_ALIGN(sizeof(struct fdt_header), -+ sizeof(struct fdt_reserve_entry)); -+ void *fdt = buf; -+ -+ if (bufsize < hdrsize) -+ return -FDT_ERR_NOSPACE; -+ -+ if (flags & ~FDT_CREATE_FLAGS_ALL) -+ return -FDT_ERR_BADFLAGS; -+ -+ memset(buf, 0, bufsize); -+ -+ /* -+ * magic and last_comp_version keep intermediate state during the fdt -+ * creation process, which is replaced with the proper FDT format by -+ * fdt_finish(). -+ * -+ * flags should be accessed with sw_flags(). -+ */ -+ fdt_set_magic(fdt, FDT_SW_MAGIC); -+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); -+ fdt_set_last_comp_version(fdt, flags); -+ -+ fdt_set_totalsize(fdt, bufsize); -+ -+ fdt_set_off_mem_rsvmap(fdt, hdrsize); -+ fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); -+ fdt_set_off_dt_strings(fdt, 0); -+ -+ return 0; -+} -+ -+int fdt_create(void *buf, int bufsize) -+{ -+ return fdt_create_with_flags(buf, bufsize, 0); -+} -+ -+int fdt_resize(void *fdt, void *buf, int bufsize) -+{ -+ size_t headsize, tailsize; -+ char *oldtail, *newtail; -+ -+ FDT_SW_PROBE(fdt); -+ -+ if (bufsize < 0) -+ return -FDT_ERR_NOSPACE; -+ -+ headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); -+ tailsize = fdt_size_dt_strings(fdt); -+ -+ if (!can_assume(VALID_DTB) && -+ headsize + tailsize > fdt_totalsize(fdt)) -+ return -FDT_ERR_INTERNAL; -+ -+ if ((headsize + tailsize) > (unsigned)bufsize) -+ return -FDT_ERR_NOSPACE; -+ -+ oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize; -+ newtail = (char *)buf + bufsize - tailsize; -+ -+ /* Two cases to avoid clobbering data if the old and new -+ * buffers partially overlap */ -+ if (buf <= fdt) { -+ memmove(buf, fdt, headsize); -+ memmove(newtail, oldtail, tailsize); -+ } else { -+ memmove(newtail, oldtail, tailsize); -+ memmove(buf, fdt, headsize); -+ } -+ -+ fdt_set_totalsize(buf, bufsize); -+ if (fdt_off_dt_strings(buf)) -+ fdt_set_off_dt_strings(buf, bufsize); -+ -+ return 0; -+} -+ -+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) -+{ -+ struct fdt_reserve_entry *re; -+ int offset; -+ -+ FDT_SW_PROBE_MEMRSV(fdt); -+ -+ offset = fdt_off_dt_struct(fdt); -+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) -+ return -FDT_ERR_NOSPACE; -+ -+ re = (struct fdt_reserve_entry *)((char *)fdt + offset); -+ re->address = cpu_to_fdt64(addr); -+ re->size = cpu_to_fdt64(size); -+ -+ fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); -+ -+ return 0; -+} -+ -+int fdt_finish_reservemap(void *fdt) -+{ -+ int err = fdt_add_reservemap_entry(fdt, 0, 0); -+ -+ if (err) -+ return err; -+ -+ fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt)); -+ return 0; -+} -+ -+int fdt_begin_node(void *fdt, const char *name) -+{ -+ struct fdt_node_header *nh; -+ int namelen; -+ -+ FDT_SW_PROBE_STRUCT(fdt); -+ -+ namelen = strlen(name) + 1; -+ nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); -+ if (! nh) -+ return -FDT_ERR_NOSPACE; -+ -+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); -+ memcpy(nh->name, name, namelen); -+ return 0; -+} -+ -+int fdt_end_node(void *fdt) -+{ -+ fdt32_t *en; -+ -+ FDT_SW_PROBE_STRUCT(fdt); -+ -+ en = fdt_grab_space_(fdt, FDT_TAGSIZE); -+ if (! en) -+ return -FDT_ERR_NOSPACE; -+ -+ *en = cpu_to_fdt32(FDT_END_NODE); -+ return 0; -+} -+ -+static int fdt_add_string_(void *fdt, const char *s) -+{ -+ char *strtab = (char *)fdt + fdt_totalsize(fdt); -+ unsigned int strtabsize = fdt_size_dt_strings(fdt); -+ unsigned int len = strlen(s) + 1; -+ unsigned int struct_top, offset; -+ -+ offset = strtabsize + len; -+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); -+ if (fdt_totalsize(fdt) - offset < struct_top) -+ return 0; /* no more room :( */ -+ -+ memcpy(strtab - offset, s, len); -+ fdt_set_size_dt_strings(fdt, strtabsize + len); -+ return -offset; -+} -+ -+/* Must only be used to roll back in case of error */ -+static void fdt_del_last_string_(void *fdt, const char *s) -+{ -+ int strtabsize = fdt_size_dt_strings(fdt); -+ int len = strlen(s) + 1; -+ -+ fdt_set_size_dt_strings(fdt, strtabsize - len); -+} -+ -+static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) -+{ -+ char *strtab = (char *)fdt + fdt_totalsize(fdt); -+ int strtabsize = fdt_size_dt_strings(fdt); -+ const char *p; -+ -+ *allocated = 0; -+ -+ p = fdt_find_string_(strtab - strtabsize, strtabsize, s); -+ if (p) -+ return p - strtab; -+ -+ *allocated = 1; -+ -+ return fdt_add_string_(fdt, s); -+} -+ -+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) -+{ -+ struct fdt_property *prop; -+ int nameoff; -+ int allocated; -+ -+ FDT_SW_PROBE_STRUCT(fdt); -+ -+ /* String de-duplication can be slow, _NO_NAME_DEDUP skips it */ -+ if (sw_flags(fdt) & FDT_CREATE_FLAG_NO_NAME_DEDUP) { -+ allocated = 1; -+ nameoff = fdt_add_string_(fdt, name); -+ } else { -+ nameoff = fdt_find_add_string_(fdt, name, &allocated); -+ } -+ if (nameoff == 0) -+ return -FDT_ERR_NOSPACE; -+ -+ prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); -+ if (! prop) { -+ if (allocated) -+ fdt_del_last_string_(fdt, name); -+ return -FDT_ERR_NOSPACE; -+ } -+ -+ prop->tag = cpu_to_fdt32(FDT_PROP); -+ prop->nameoff = cpu_to_fdt32(nameoff); -+ prop->len = cpu_to_fdt32(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; -+} -+ -+int fdt_finish(void *fdt) -+{ -+ char *p = (char *)fdt; -+ fdt32_t *end; -+ int oldstroffset, newstroffset; -+ uint32_t tag; -+ int offset, nextoffset; -+ -+ FDT_SW_PROBE_STRUCT(fdt); -+ -+ /* Add terminator */ -+ end = fdt_grab_space_(fdt, sizeof(*end)); -+ if (! end) -+ return -FDT_ERR_NOSPACE; -+ *end = cpu_to_fdt32(FDT_END); -+ -+ /* Relocate the string table */ -+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); -+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); -+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); -+ fdt_set_off_dt_strings(fdt, newstroffset); -+ -+ /* Walk the structure, correcting string offsets */ -+ offset = 0; -+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { -+ if (tag == FDT_PROP) { -+ struct fdt_property *prop = -+ fdt_offset_ptr_w_(fdt, offset); -+ int nameoff; -+ -+ nameoff = fdt32_to_cpu(prop->nameoff); -+ nameoff += fdt_size_dt_strings(fdt); -+ prop->nameoff = cpu_to_fdt32(nameoff); -+ } -+ offset = nextoffset; -+ } -+ if (nextoffset < 0) -+ return nextoffset; -+ -+ /* Finally, adjust the header */ -+ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); -+ -+ /* And fix up fields that were keeping intermediate state. */ -+ fdt_set_last_comp_version(fdt, FDT_LAST_COMPATIBLE_VERSION); -+ fdt_set_magic(fdt, FDT_MAGIC); -+ -+ return 0; -+} -diff --git a/common/libfdt/fdt_wip.c b/common/libfdt/fdt_wip.c -new file mode 100644 -index 0000000..c2d7566 ---- /dev/null -+++ b/common/libfdt/fdt_wip.c -@@ -0,0 +1,94 @@ -+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#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 ((unsigned)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) -+{ -+ const void *propval; -+ int proplen; -+ -+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen); -+ if (!propval) -+ return proplen; -+ -+ if (proplen != len) -+ return -FDT_ERR_NOSPACE; -+ -+ return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, -+ strlen(name), 0, -+ val, len); -+} -+ -+static void fdt_nop_region_(void *start, int len) -+{ -+ fdt32_t *p; -+ -+ for (p = start; (char *)p < ((char *)start + len); p++) -+ *p = cpu_to_fdt32(FDT_NOP); -+} -+ -+int fdt_nop_property(void *fdt, int nodeoffset, const char *name) -+{ -+ struct fdt_property *prop; -+ int len; -+ -+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -+ if (!prop) -+ return len; -+ -+ fdt_nop_region_(prop, len + sizeof(*prop)); -+ -+ return 0; -+} -+ -+int fdt_node_end_offset_(void *fdt, int offset) -+{ -+ int depth = 0; -+ -+ while ((offset >= 0) && (depth >= 0)) -+ offset = fdt_next_node(fdt, offset, &depth); -+ -+ return offset; -+} -+ -+int fdt_nop_node(void *fdt, int nodeoffset) -+{ -+ int endoffset; -+ -+ endoffset = fdt_node_end_offset_(fdt, nodeoffset); -+ if (endoffset < 0) -+ return endoffset; -+ -+ fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0), -+ endoffset - nodeoffset); -+ return 0; -+} -diff --git a/common/libfdt/libfdt_internal.h b/common/libfdt/libfdt_internal.h -new file mode 100644 -index 0000000..16bda19 ---- /dev/null -+++ b/common/libfdt/libfdt_internal.h -@@ -0,0 +1,192 @@ -+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ -+#ifndef LIBFDT_INTERNAL_H -+#define LIBFDT_INTERNAL_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+#include -+ -+#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -+#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) -+ -+int32_t fdt_ro_probe_(const void *fdt); -+#define FDT_RO_PROBE(fdt) \ -+ { \ -+ int32_t totalsize_; \ -+ if ((totalsize_ = fdt_ro_probe_(fdt)) < 0) \ -+ return totalsize_; \ -+ } -+ -+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) -+{ -+ return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; -+} -+ -+static inline void *fdt_offset_ptr_w_(void *fdt, int 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) -+{ -+ const struct fdt_reserve_entry *rsv_table = -+ (const struct fdt_reserve_entry *) -+ ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); -+ -+ return rsv_table + n; -+} -+static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) -+{ -+ return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); -+} -+ -+/* -+ * Internal helpers to access tructural elements of the device tree -+ * blob (rather than for exaple reading integers from within property -+ * values). We assume that we are either given a naturally aligned -+ * address for the platform or if we are not, we are on a platform -+ * where unaligned memory reads will be handled in a graceful manner. -+ * If not the external helpers fdtXX_ld() from libfdt.h can be used -+ * instead. -+ */ -+static inline uint32_t fdt32_ld_(const fdt32_t *p) -+{ -+ return fdt32_to_cpu(*p); -+} -+ -+static inline uint64_t fdt64_ld_(const fdt64_t *p) -+{ -+ return fdt64_to_cpu(*p); -+} -+ -+#define FDT_SW_MAGIC (~FDT_MAGIC) -+ -+/**********************************************************************/ -+/* Checking controls */ -+/**********************************************************************/ -+ -+#ifndef FDT_ASSUME_MASK -+#define FDT_ASSUME_MASK 0 -+#endif -+ -+/* -+ * Defines assumptions which can be enabled. Each of these can be enabled -+ * individually. For maximum safety, don't enable any assumptions! -+ * -+ * For minimal code size and no safety, use ASSUME_PERFECT at your own risk. -+ * You should have another method of validating the device tree, such as a -+ * signature or hash check before using libfdt. -+ * -+ * For situations where security is not a concern it may be safe to enable -+ * ASSUME_SANE. -+ */ -+enum { -+ /* -+ * This does essentially no checks. Only the latest device-tree -+ * version is correctly handled. Inconsistencies or errors in the device -+ * tree may cause undefined behaviour or crashes. Invalid parameters -+ * passed to libfdt may do the same. -+ * -+ * If an error occurs when modifying the tree it may leave the tree in -+ * an intermediate (but valid) state. As an example, adding a property -+ * where there is insufficient space may result in the property name -+ * being added to the string table even though the property itself is -+ * not added to the struct section. -+ * -+ * Only use this if you have a fully validated device tree with -+ * the latest supported version and wish to minimise code size. -+ */ -+ ASSUME_PERFECT = 0xff, -+ -+ /* -+ * This assumes that the device tree is sane. i.e. header metadata -+ * and basic hierarchy are correct. -+ * -+ * With this assumption enabled, normal device trees produced by libfdt -+ * and the compiler should be handled safely. Malicious device trees and -+ * complete garbage may cause libfdt to behave badly or crash. Truncated -+ * device trees (e.g. those only partially loaded) can also cause -+ * problems. -+ * -+ * Note: Only checks that relate exclusively to the device tree itself -+ * (not the parameters passed to libfdt) are disabled by this -+ * assumption. This includes checking headers, tags and the like. -+ */ -+ ASSUME_VALID_DTB = 1 << 0, -+ -+ /* -+ * This builds on ASSUME_VALID_DTB and further assumes that libfdt -+ * functions are called with valid parameters, i.e. not trigger -+ * FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any -+ * extensive checking of parameters and the device tree, making various -+ * assumptions about correctness. -+ * -+ * It doesn't make sense to enable this assumption unless -+ * ASSUME_VALID_DTB is also enabled. -+ */ -+ ASSUME_VALID_INPUT = 1 << 1, -+ -+ /* -+ * This disables checks for device-tree version and removes all code -+ * which handles older versions. -+ * -+ * Only enable this if you know you have a device tree with the latest -+ * version. -+ */ -+ ASSUME_LATEST = 1 << 2, -+ -+ /* -+ * This assumes that it is OK for a failed addition to the device tree, -+ * due to lack of space or some other problem, to skip any rollback -+ * steps (such as dropping the property name from the string table). -+ * This is safe to enable in most circumstances, even though it may -+ * leave the tree in a sub-optimal state. -+ */ -+ ASSUME_NO_ROLLBACK = 1 << 3, -+ -+ /* -+ * This assumes that the device tree components appear in a 'convenient' -+ * order, i.e. the memory reservation block first, then the structure -+ * block and finally the string block. -+ * -+ * This order is not specified by the device-tree specification, -+ * but is expected by libfdt. The device-tree compiler always created -+ * device trees with this order. -+ * -+ * This assumption disables a check in fdt_open_into() and removes the -+ * ability to fix the problem there. This is safe if you know that the -+ * device tree is correctly ordered. See fdt_blocks_misordered_(). -+ */ -+ ASSUME_LIBFDT_ORDER = 1 << 4, -+ -+ /* -+ * This assumes that libfdt itself does not have any internal bugs. It -+ * drops certain checks that should never be needed unless libfdt has an -+ * undiscovered bug. -+ * -+ * This can generally be considered safe to enable. -+ */ -+ ASSUME_LIBFDT_FLAWLESS = 1 << 5, -+}; -+ -+/** -+ * can_assume_() - check if a particular assumption is enabled -+ * -+ * @mask: Mask to check (ASSUME_...) -+ * @return true if that assumption is enabled, else false -+ */ -+static inline bool can_assume_(int mask) -+{ -+ return FDT_ASSUME_MASK & mask; -+} -+ -+/** helper macros for checking assumptions */ -+#define can_assume(_assume) can_assume_(ASSUME_ ## _assume) -+ -+#endif /* LIBFDT_INTERNAL_H */ -diff --git a/include/fdt.h b/include/fdt.h -new file mode 100644 -index 0000000..f2e6880 ---- /dev/null -+++ b/include/fdt.h -@@ -0,0 +1,66 @@ -+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ -+#ifndef FDT_H -+#define FDT_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * Copyright 2012 Kim Phillips, Freescale Semiconductor. -+ */ -+ -+#ifndef __ASSEMBLY__ -+ -+struct fdt_header { -+ fdt32_t magic; /* magic word FDT_MAGIC */ -+ fdt32_t totalsize; /* total size of DT block */ -+ fdt32_t off_dt_struct; /* offset to structure */ -+ fdt32_t off_dt_strings; /* offset to strings */ -+ fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ -+ fdt32_t version; /* format version */ -+ fdt32_t last_comp_version; /* last compatible version */ -+ -+ /* version 2 fields below */ -+ fdt32_t boot_cpuid_phys; /* Which physical CPU id we're -+ booting on */ -+ /* version 3 fields below */ -+ fdt32_t size_dt_strings; /* size of the strings block */ -+ -+ /* version 17 fields below */ -+ fdt32_t size_dt_struct; /* size of the structure block */ -+}; -+ -+struct fdt_reserve_entry { -+ fdt64_t address; -+ fdt64_t size; -+}; -+ -+struct fdt_node_header { -+ fdt32_t tag; -+ char name[0]; -+}; -+ -+struct fdt_property { -+ fdt32_t tag; -+ fdt32_t len; -+ fdt32_t nameoff; -+ char data[0]; -+}; -+ -+#endif /* !__ASSEMBLY */ -+ -+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -+#define FDT_TAGSIZE sizeof(fdt32_t) -+ -+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ -+#define FDT_END_NODE 0x2 /* End node */ -+#define FDT_PROP 0x3 /* Property: name off, -+ size, content */ -+#define FDT_NOP 0x4 /* nop */ -+#define FDT_END 0x9 -+ -+#define FDT_V1_SIZE (7*sizeof(fdt32_t)) -+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) -+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) -+#define FDT_V16_SIZE FDT_V3_SIZE -+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) -+ -+#endif /* FDT_H */ -diff --git a/include/libfdt.h b/include/libfdt.h -new file mode 100644 -index 0000000..a7f432c ---- /dev/null -+++ b/include/libfdt.h -@@ -0,0 +1,2147 @@ -+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ -+#ifndef LIBFDT_H -+#define LIBFDT_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ */ -+ -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define FDT_FIRST_SUPPORTED_VERSION 0x02 -+#define FDT_LAST_COMPATIBLE_VERSION 0x10 -+#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: Attempted to create a node or property which -+ * already exists */ -+#define FDT_ERR_NOSPACE 3 -+ /* FDT_ERR_NOSPACE: Operation needed to expand the device -+ * tree, but its buffer did not have sufficient space to -+ * contain the expanded tree. Use fdt_open_into() to move the -+ * device tree to a buffer with more space. */ -+ -+/* Error codes: codes for bad parameters */ -+#define FDT_ERR_BADOFFSET 4 -+ /* FDT_ERR_BADOFFSET: Function was passed a structure block -+ * offset which is out-of-bounds, or which points to an -+ * unsuitable part of the structure for the operation. */ -+#define FDT_ERR_BADPATH 5 -+ /* FDT_ERR_BADPATH: Function was passed a badly formatted path -+ * (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. -+ * 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 -+ * not sufficiently complete for the requested operation. */ -+ -+/* Error codes: codes for bad device tree blobs */ -+#define FDT_ERR_TRUNCATED 8 -+ /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly -+ * terminated (overflows, goes outside allowed bounds, or -+ * isn't properly terminated). */ -+#define FDT_ERR_BADMAGIC 9 -+ /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a -+ * device tree at all - it is missing the flattened device -+ * tree magic number. */ -+#define FDT_ERR_BADVERSION 10 -+ /* FDT_ERR_BADVERSION: Given device tree has a version which -+ * can't be handled by the requested operation. For -+ * read-write functions, this may mean that fdt_open_into() is -+ * required to convert the tree to the expected version. */ -+#define FDT_ERR_BADSTRUCTURE 11 -+ /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt -+ * structure block or other serious error (e.g. misnested -+ * nodes, or subnodes preceding properties). */ -+#define FDT_ERR_BADLAYOUT 12 -+ /* FDT_ERR_BADLAYOUT: For read-write functions, the given -+ * device tree has it's sub-blocks in an order that the -+ * function can't handle (memory reserve map, then structure, -+ * then strings). Use fdt_open_into() to reorganize the tree -+ * into a form suitable for the read-write operations. */ -+ -+/* "Can't happen" error indicating a bug in libfdt */ -+#define FDT_ERR_INTERNAL 13 -+ /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. -+ * Should never be returned, if it is, it indicates a bug in -+ * libfdt itself. */ -+ -+/* Errors in device tree content */ -+#define FDT_ERR_BADNCELLS 14 -+ /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells -+ * or similar property with a bad format or value */ -+ -+#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_BADFLAGS 18 -+ /* FDT_ERR_BADFLAGS: The function was passed a flags field that -+ * contains invalid flags or an invalid combination of flags. */ -+ -+#define FDT_ERR_ALIGNMENT 19 -+ /* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte -+ * aligned. */ -+ -+#define FDT_ERR_MAX 19 -+ -+/* constants */ -+#define FDT_MAX_PHANDLE 0xfffffffe -+ /* Valid values for phandles range from 1 to 2^32-2. */ -+ -+/**********************************************************************/ -+/* 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); -+} -+ -+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); -+ -+/* -+ * External helpers to access words from a device tree blob. They're built -+ * to work even with unaligned pointers on platforms (such as ARMv5) that don't -+ * like unaligned loads and stores. -+ */ -+static inline uint16_t fdt16_ld(const fdt16_t *p) -+{ -+ const uint8_t *bp = (const uint8_t *)p; -+ -+ return ((uint16_t)bp[0] << 8) | bp[1]; -+} -+ -+static inline uint32_t fdt32_ld(const fdt32_t *p) -+{ -+ const uint8_t *bp = (const uint8_t *)p; -+ -+ return ((uint32_t)bp[0] << 24) -+ | ((uint32_t)bp[1] << 16) -+ | ((uint32_t)bp[2] << 8) -+ | bp[3]; -+} -+ -+static inline void fdt32_st(void *property, uint32_t value) -+{ -+ uint8_t *bp = (uint8_t *)property; -+ -+ bp[0] = value >> 24; -+ bp[1] = (value >> 16) & 0xff; -+ bp[2] = (value >> 8) & 0xff; -+ bp[3] = value & 0xff; -+} -+ -+static inline uint64_t fdt64_ld(const fdt64_t *p) -+{ -+ const uint8_t *bp = (const uint8_t *)p; -+ -+ return ((uint64_t)bp[0] << 56) -+ | ((uint64_t)bp[1] << 48) -+ | ((uint64_t)bp[2] << 40) -+ | ((uint64_t)bp[3] << 32) -+ | ((uint64_t)bp[4] << 24) -+ | ((uint64_t)bp[5] << 16) -+ | ((uint64_t)bp[6] << 8) -+ | bp[7]; -+} -+ -+static inline void fdt64_st(void *property, uint64_t value) -+{ -+ uint8_t *bp = (uint8_t *)property; -+ -+ bp[0] = value >> 56; -+ bp[1] = (value >> 48) & 0xff; -+ bp[2] = (value >> 40) & 0xff; -+ bp[3] = (value >> 32) & 0xff; -+ bp[4] = (value >> 24) & 0xff; -+ bp[5] = (value >> 16) & 0xff; -+ bp[6] = (value >> 8) & 0xff; -+ bp[7] = value & 0xff; -+} -+ -+/**********************************************************************/ -+/* Traversal functions */ -+/**********************************************************************/ -+ -+int fdt_next_node(const void *fdt, int offset, int *depth); -+ -+/** -+ * fdt_first_subnode() - get offset of first direct subnode -+ * @fdt: FDT blob -+ * @offset: Offset of node to check -+ * -+ * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none -+ */ -+int fdt_first_subnode(const void *fdt, int offset); -+ -+/** -+ * fdt_next_subnode() - get offset of next direct subnode -+ * @fdt: FDT blob -+ * @offset: Offset of previous subnode -+ * -+ * After first calling fdt_first_subnode(), call this function repeatedly to -+ * get direct subnodes of a parent node. -+ * -+ * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more -+ * subnodes -+ */ -+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_NOTFOUND)) { -+ * 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_ld(&((const struct fdt_header *)(fdt))->field)) -+#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_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) -+ -+#define fdt_set_hdr_(name) \ -+ static inline void fdt_set_##name(void *fdt, uint32_t val) \ -+ { \ -+ 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_header_size - return the size of the tree's header -+ * @fdt: pointer to a flattened device tree -+ * -+ * Return: size of DTB header in bytes -+ */ -+size_t fdt_header_size(const void *fdt); -+ -+/** -+ * fdt_header_size_ - internal function to get header size from a version number -+ * @version: devicetree version number -+ * -+ * Return: size of DTB header in bytes -+ */ -+size_t fdt_header_size_(uint32_t version); -+ -+/** -+ * fdt_check_header - sanity check a device tree header -+ * @fdt: pointer to data which might be a flattened device tree -+ * -+ * fdt_check_header() checks that the given buffer contains what -+ * appears to be a flattened device tree, and that the header contains -+ * valid information (to the extent that can be determined from the -+ * header alone). -+ * -+ * returns: -+ * 0, if the buffer appears to contain a valid device tree -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_TRUNCATED, standard meanings, as above -+ */ -+int fdt_check_header(const void *fdt); -+ -+/** -+ * fdt_move - move a device tree around in memory -+ * @fdt: pointer to the device tree to move -+ * @buf: pointer to memory where the device is to be moved -+ * @bufsize: size of the memory space at buf -+ * -+ * fdt_move() relocates, if possible, the device tree blob located at -+ * fdt to the buffer at buf of size bufsize. The buffer may overlap -+ * with the existing device tree blob at fdt. Therefore, -+ * fdt_move(fdt, fdt, fdt_totalsize(fdt)) -+ * should always succeed. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+int fdt_move(const void *fdt, void *buf, int bufsize); -+ -+/**********************************************************************/ -+/* Read-only functions */ -+/**********************************************************************/ -+ -+int fdt_check_full(const void *fdt, size_t bufsize); -+ -+/** -+ * fdt_get_string - retrieve a string from the strings block of a device tree -+ * @fdt: pointer to the device tree blob -+ * @stroffset: offset of the string within the strings block (native endian) -+ * @lenp: optional pointer to return the string's length -+ * -+ * fdt_get_string() retrieves a pointer to a single string from the -+ * strings block of the device tree blob at fdt, and optionally also -+ * returns the string's length in *lenp. -+ * -+ * returns: -+ * a pointer to the string, on success -+ * NULL, if stroffset is out of bounds, or doesn't point to a valid string -+ */ -+const char *fdt_get_string(const void *fdt, int stroffset, int *lenp); -+ -+/** -+ * fdt_string - retrieve a string from the strings block of a device tree -+ * @fdt: pointer to the device tree blob -+ * @stroffset: offset of the string within the strings block (native endian) -+ * -+ * fdt_string() retrieves a pointer to a single string from the -+ * strings block of the device tree blob at fdt. -+ * -+ * returns: -+ * a pointer to the string, on success -+ * NULL, if stroffset is out of bounds, or doesn't point to a valid string -+ */ -+const char *fdt_string(const void *fdt, int stroffset); -+ -+/** -+ * fdt_find_max_phandle - find and return the highest phandle in a tree -+ * @fdt: pointer to the device tree blob -+ * @phandle: return location for the highest phandle value found in the tree -+ * -+ * fdt_find_max_phandle() finds the highest phandle value in the given device -+ * tree. The value returned in @phandle is only valid if the function returns -+ * success. -+ * -+ * returns: -+ * 0 on success or a negative error code on failure -+ */ -+int fdt_find_max_phandle(const void *fdt, uint32_t *phandle); -+ -+/** -+ * 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. -+ * -+ * This function is deprecated in favour of fdt_find_max_phandle(). -+ * -+ * returns: -+ * the highest phandle on success -+ * 0, if no phandle was found in the device tree -+ * -1, if an error occurred -+ */ -+static inline uint32_t fdt_get_max_phandle(const void *fdt) -+{ -+ uint32_t phandle; -+ int err; -+ -+ err = fdt_find_max_phandle(fdt, &phandle); -+ if (err < 0) -+ return (uint32_t)-1; -+ -+ return phandle; -+} -+ -+/** -+ * fdt_generate_phandle - return a new, unused phandle for a device tree blob -+ * @fdt: pointer to the device tree blob -+ * @phandle: return location for the new phandle -+ * -+ * Walks the device tree blob and looks for the highest phandle value. On -+ * success, the new, unused phandle value (one higher than the previously -+ * highest phandle value in the device tree blob) will be returned in the -+ * @phandle parameter. -+ * -+ * Return: 0 on success or a negative error-code on failure -+ */ -+int fdt_generate_phandle(const void *fdt, uint32_t *phandle); -+ -+/** -+ * fdt_num_mem_rsv - retrieve the number of memory reserve map entries -+ * @fdt: pointer to the device tree blob -+ * -+ * Returns the number of entries in the device tree blob's memory -+ * reservation map. This does not include the terminating 0,0 entry -+ * or any other (0,0) entries reserved for expansion. -+ * -+ * returns: -+ * the number of entries -+ */ -+int fdt_num_mem_rsv(const void *fdt); -+ -+/** -+ * fdt_get_mem_rsv - retrieve one memory reserve map entry -+ * @fdt: pointer to the device tree blob -+ * @n: index of reserve map entry -+ * @address: pointer to 64-bit variable to hold the start address -+ * @size: pointer to 64-bit variable to hold the size of the entry -+ * -+ * On success, @address and @size will contain the address and size of -+ * the n-th reserve map entry from the device tree blob, in -+ * native-endian format. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); -+ -+/** -+ * fdt_subnode_offset_namelen - find a subnode based on substring -+ * @fdt: pointer to the device tree blob -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to locate -+ * @namelen: number of characters of name to consider -+ * -+ * Identical to fdt_subnode_offset(), but only examine the first -+ * namelen characters of name for matching the subnode name. This is -+ * useful for finding subnodes based on a portion of a larger string, -+ * such as a full path. -+ * -+ * Return: offset of the subnode or -FDT_ERR_NOTFOUND if name not found. -+ */ -+#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 -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to locate -+ * -+ * fdt_subnode_offset() finds a subnode of the node at structure block -+ * offset parentoffset with the given name. name may include a unit -+ * address, in which case fdt_subnode_offset() will find the subnode -+ * with that unit address, or the unit address may be omitted, in -+ * which case fdt_subnode_offset() will find an arbitrary subnode -+ * whose name excluding unit address matches the given name. -+ * -+ * 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_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+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. -+ * -+ * Return: offset of the node or negative libfdt error value otherwise -+ */ -+#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 -+ * @path: full path of the node to locate -+ * -+ * fdt_path_offset() finds a node of a given path in the device tree. -+ * Each path component may omit the unit address portion, but the -+ * results of this are undefined if any such path component is -+ * ambiguous (that is if there are multiple nodes at the relevant -+ * level matching the given component, differentiated only by unit -+ * address). -+ * -+ * returns: -+ * 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, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_path_offset(const void *fdt, const char *path); -+ -+/** -+ * fdt_get_name - retrieve the name of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of the starting node -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_get_name() retrieves the name (including unit address) of the -+ * device tree node at structure block offset nodeoffset. If lenp is -+ * non-NULL, the length of this name is also returned, in the integer -+ * pointed to by lenp. -+ * -+ * returns: -+ * pointer to the node's name, on success -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); -+ -+/** -+ * fdt_first_property_offset - find the offset of a node's first property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of a node -+ * -+ * fdt_first_property_offset() finds the first property of the node at -+ * the given structure block offset. -+ * -+ * returns: -+ * structure block offset of the property (>=0), on success -+ * -FDT_ERR_NOTFOUND, if the requested node has no properties -+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_first_property_offset(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_next_property_offset - step through a node's properties -+ * @fdt: pointer to the device tree blob -+ * @offset: structure block offset of a property -+ * -+ * fdt_next_property_offset() finds the property immediately after the -+ * one at the given structure block offset. This will be a property -+ * of the same node as the given property. -+ * -+ * returns: -+ * structure block offset of the next property (>=0), on success -+ * -FDT_ERR_NOTFOUND, if the given property is the last in its node -+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_next_property_offset(const void *fdt, int offset); -+ -+/** -+ * fdt_for_each_property_offset - iterate over all properties of a node -+ * -+ * @property: 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_NOTFOUND)) { -+ * 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 -+ * @offset: offset of the property to retrieve -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_get_property_by_offset() retrieves a pointer to the -+ * fdt_property structure within the device tree blob at the given -+ * 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 -+ * value (>=0) -+ * NULL, on error -+ * if lenp is non-NULL, *lenp contains an error code (<0): -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+const struct fdt_property *fdt_get_property_by_offset(const void *fdt, -+ int offset, -+ int *lenp); -+ -+/** -+ * fdt_get_property_namelen - find a property based on substring -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @namelen: number of characters of name to consider -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * Identical to fdt_get_property(), but only examine the first namelen -+ * characters of name for matching the property name. -+ * -+ * Return: pointer to the structure representing the property, or NULL -+ * if not found -+ */ -+#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 -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_get_property() retrieves a pointer to the fdt_property -+ * structure within the device tree blob corresponding to the property -+ * named 'name' of the node at offset nodeoffset. If lenp is -+ * non-NULL, the length of the property value is also returned, in the -+ * integer pointed to by lenp. -+ * -+ * returns: -+ * pointer to the structure representing the property -+ * if lenp is non-NULL, *lenp contains the length of the property -+ * value (>=0) -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, -+ const char *name, int *lenp); -+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, -+ const char *name, -+ int *lenp) -+{ -+ return (struct fdt_property *)(uintptr_t) -+ fdt_get_property(fdt, nodeoffset, name, lenp); -+} -+ -+/** -+ * fdt_getprop_by_offset - retrieve the value of a property at a given offset -+ * @fdt: pointer to the device tree blob -+ * @offset: offset of the property to read -+ * @namep: pointer to a string variable (will be overwritten) or NULL -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_getprop_by_offset() retrieves a pointer to the value of the -+ * property at structure block offset 'offset' (this will be a pointer -+ * to within the device blob itself, not a copy of the value). If -+ * lenp is non-NULL, the length of the property value is also -+ * returned, in the integer pointed to by lenp. If namep is non-NULL, -+ * the property's namne will also be returned in the char * pointed to -+ * by namep (this will be a pointer to within the device tree's string -+ * block, not a new copy of the name). -+ * -+ * returns: -+ * pointer to the property's value -+ * if lenp is non-NULL, *lenp contains the length of the property -+ * value (>=0) -+ * if namep is non-NULL *namep contiains a pointer to the property -+ * name. -+ * NULL, on error -+ * if lenp is non-NULL, *lenp contains an error code (<0): -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -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 -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @namelen: number of characters of name to consider -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * Identical to fdt_getprop(), but only examine the first namelen -+ * characters of name for matching the property name. -+ * -+ * Return: pointer to the property's value or NULL on error -+ */ -+#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 -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_getprop() retrieves a pointer to the value of the property -+ * named @name of the node at offset @nodeoffset (this will be a -+ * pointer to within the device blob itself, not a copy of the value). -+ * If @lenp is non-NULL, the length of the property value is also -+ * returned, in the integer pointed to by @lenp. -+ * -+ * returns: -+ * pointer to the property's value -+ * if lenp is non-NULL, *lenp contains the length of the property -+ * value (>=0) -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+const void *fdt_getprop(const void *fdt, int nodeoffset, -+ const char *name, int *lenp); -+static inline void *fdt_getprop_w(void *fdt, int nodeoffset, -+ const char *name, int *lenp) -+{ -+ return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); -+} -+ -+/** -+ * fdt_get_phandle - retrieve the phandle of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of the node -+ * -+ * fdt_get_phandle() retrieves the phandle of the device tree node at -+ * structure block offset nodeoffset. -+ * -+ * returns: -+ * the phandle of the node at nodeoffset, on success (!= 0, != -1) -+ * 0, if the node has no phandle, or another error occurs -+ */ -+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_get_alias_namelen - get alias based on substring -+ * @fdt: pointer to the device tree blob -+ * @name: name of the alias th look up -+ * @namelen: number of characters of name to consider -+ * -+ * Identical to fdt_get_alias(), but only examine the first @namelen -+ * characters of @name for matching the alias name. -+ * -+ * Return: a pointer to the expansion of the alias named @name, if it exists, -+ * NULL otherwise -+ */ -+#ifndef SWIG /* Not available in Python */ -+const char *fdt_get_alias_namelen(const void *fdt, -+ const char *name, int namelen); -+#endif -+ -+/** -+ * 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 -+ * -+ * fdt_get_alias() retrieves the value of a given alias. That is, the -+ * value of the property named @name in the node /aliases. -+ * -+ * returns: -+ * a pointer to the expansion of the alias named 'name', if it exists -+ * NULL, if the given alias or the /aliases node does not exist -+ */ -+const char *fdt_get_alias(const void *fdt, const char *name); -+ -+/** -+ * fdt_get_path - determine the full path of a node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose path to find -+ * @buf: character buffer to contain the returned path (will be overwritten) -+ * @buflen: size of the character buffer at buf -+ * -+ * fdt_get_path() computes the full path of the node at offset -+ * nodeoffset, and records that path in the buffer at buf. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset. -+ * -+ * returns: -+ * 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_NOSPACE, the path of the given node is longer than (bufsize-1) -+ * characters and will not fit in the given buffer. -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); -+ -+/** -+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * @supernodedepth: depth of the ancestor to find -+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node -+ * at a specific depth from the root (where the root itself has depth -+ * 0, its immediate subnodes depth 1 and so forth). So -+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); -+ * will always return 0, the offset of the root node. If the node at -+ * nodeoffset has depth D, then: -+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); -+ * will return nodeoffset itself. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, -+ int supernodedepth, int *nodedepth); -+ -+/** -+ * fdt_node_depth - find the depth of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * -+ * fdt_node_depth() finds the depth of a given node. The root node -+ * has depth 0, its immediate subnodes depth 1 and so forth. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_depth(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_parent_offset - find the parent of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * -+ * fdt_parent_offset() locates the parent node of a given node (that -+ * is, it finds the offset of the node which contains the node at -+ * nodeoffset as a subnode). -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset, *twice*. -+ * -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_parent_offset(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_node_offset_by_prop_value - find nodes with a given property value -+ * @fdt: pointer to the device tree blob -+ * @startoffset: only find nodes after this offset -+ * @propname: property name to check -+ * @propval: property value to search for -+ * @proplen: length of the value in propval -+ * -+ * fdt_node_offset_by_prop_value() returns the offset of the first -+ * node after startoffset, which has a property named propname whose -+ * value is of length proplen and has value equal to propval; or if -+ * startoffset is -1, the very first such node in the tree. -+ * -+ * To iterate through all nodes matching the criterion, the following -+ * idiom can be used: -+ * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, -+ * propval, proplen); -+ * while (offset != -FDT_ERR_NOTFOUND) { -+ * // other code here -+ * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, -+ * propval, proplen); -+ * } -+ * -+ * Note the -1 in the first call to the function, if 0 is used here -+ * instead, the function will never locate the root node, even if it -+ * matches the criterion. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0, >startoffset), -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, -+ const char *propname, -+ const void *propval, int proplen); -+ -+/** -+ * fdt_node_offset_by_phandle - find the node with a given phandle -+ * @fdt: pointer to the device tree blob -+ * @phandle: phandle value -+ * -+ * fdt_node_offset_by_phandle() returns the offset of the node -+ * which has the given phandle value. If there is more than one node -+ * in the tree with the given phandle (an invalid tree), results are -+ * undefined. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0), on success -+ * -FDT_ERR_NOTFOUND, no node with that phandle exists -+ * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); -+ -+/** -+ * fdt_node_check_compatible - check a node's compatible property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of a tree node -+ * @compatible: string to match against -+ * -+ * fdt_node_check_compatible() returns 0 if the given node contains a -+ * @compatible property with the given string as one of its elements, -+ * it returns non-zero otherwise, or on error. -+ * -+ * returns: -+ * 0, if the node has a 'compatible' property listing the given string -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_check_compatible(const void *fdt, int nodeoffset, -+ const char *compatible); -+ -+/** -+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value -+ * @fdt: pointer to the device tree blob -+ * @startoffset: only find nodes after this offset -+ * @compatible: 'compatible' string to match against -+ * -+ * fdt_node_offset_by_compatible() returns the offset of the first -+ * node after startoffset, which has a 'compatible' property which -+ * lists the given compatible string; or if startoffset is -1, the -+ * very first such node in the tree. -+ * -+ * To iterate through all nodes matching the criterion, the following -+ * idiom can be used: -+ * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); -+ * while (offset != -FDT_ERR_NOTFOUND) { -+ * // other code here -+ * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); -+ * } -+ * -+ * Note the -1 in the first call to the function, if 0 is used here -+ * instead, the function will never locate the root node, even if it -+ * matches the criterion. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0, >startoffset), -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -+ const char *compatible); -+ -+/** -+ * fdt_stringlist_contains - check a string list property for a string -+ * @strlist: Property containing a list of strings to check -+ * @listlen: Length of property -+ * @str: String to search for -+ * -+ * This is a utility function provided for convenience. The list contains -+ * one or more strings, each terminated by \0, as is found in a device tree -+ * "compatible" property. -+ * -+ * Return: 1 if the string is found in the list, 0 not found, or invalid list -+ */ -+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) */ -+/**********************************************************************/ -+ -+/** -+ * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells -+ * -+ * This is the maximum value for #address-cells, #size-cells and -+ * similar properties that will be processed by libfdt. IEE1275 -+ * requires that OF implementations handle values up to 4. -+ * Implementations may support larger values, but in practice higher -+ * values aren't used. -+ */ -+#define FDT_MAX_NCELLS 4 -+ -+/** -+ * fdt_address_cells - retrieve address size for a bus represented in the tree -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node to find the address size for -+ * -+ * When the node has a valid #address-cells property, returns its value. -+ * -+ * 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_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_address_cells(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_size_cells - retrieve address range size for a bus represented in the -+ * tree -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node to find the address range size for -+ * -+ * When the node has a valid #size-cells property, returns its value. -+ * -+ * returns: -+ * 0 <= n < FDT_MAX_NCELLS, on success -+ * 1, if the node has no #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, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+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. -+ * -+ * Return: 0 on success, negative libfdt error value otherwise -+ */ -+#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 -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: pointer to data to replace the property value with -+ * @len: length of the property value -+ * -+ * fdt_setprop_inplace() replaces the value of a given property with -+ * the data in val, of length len. This function cannot change the -+ * size of a property, and so will only work if len is equal to the -+ * current length of the property. -+ * -+ * This function will alter only the bytes in the blob which contain -+ * the given property value, and will not alter or move any other part -+ * of the tree. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, if len is not equal to the property's current length -+ * -FDT_ERR_NOTFOUND, node does not have the named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -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 -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: 32-bit integer value to replace the property with -+ * -+ * fdt_setprop_inplace_u32() replaces the value of a given property -+ * with the 32-bit integer value in val, converting val to big-endian -+ * if necessary. This function cannot change the size of a property, -+ * and so will only work if the property already exists and has length -+ * 4. -+ * -+ * This function will alter only the bytes in the blob which contain -+ * the given property value, and will not alter or move any other part -+ * of the tree. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 -+ * -FDT_ERR_NOTFOUND, node does not have the named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, -+ const char *name, uint32_t val) -+{ -+ fdt32_t tmp = cpu_to_fdt32(val); -+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: 64-bit integer value to replace the property with -+ * -+ * fdt_setprop_inplace_u64() replaces the value of a given property -+ * with the 64-bit integer value in val, converting val to big-endian -+ * if necessary. This function cannot change the size of a property, -+ * and so will only work if the property already exists and has length -+ * 8. -+ * -+ * This function will alter only the bytes in the blob which contain -+ * the given property value, and will not alter or move any other part -+ * of the tree. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 -+ * -FDT_ERR_NOTFOUND, node does not have the named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, -+ const char *name, uint64_t val) -+{ -+ fdt64_t tmp = cpu_to_fdt64(val); -+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_setprop_inplace_cell - change the value of a single-cell property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node containing the property -+ * @name: name of the property to change the value of -+ * @val: new value of the 32-bit cell -+ * -+ * This is an alternative name for fdt_setprop_inplace_u32() -+ * Return: 0 on success, negative libfdt error number otherwise. -+ */ -+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, -+ const char *name, uint32_t val) -+{ -+ return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); -+} -+ -+/** -+ * fdt_nop_property - replace a property with nop tags -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to nop -+ * @name: name of the property to nop -+ * -+ * fdt_nop_property() will replace a given property's representation -+ * in the blob with FDT_NOP tags, effectively removing it from the -+ * tree. -+ * -+ * This function will alter only the bytes in the blob which contain -+ * the property, and will not alter or move any other part of the -+ * tree. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOTFOUND, node does not have the named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_nop_property(void *fdt, int nodeoffset, const char *name); -+ -+/** -+ * fdt_nop_node - replace a node (subtree) with nop tags -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node to nop -+ * -+ * fdt_nop_node() will replace a given node's representation in the -+ * blob, including all its subnodes, if any, with FDT_NOP tags, -+ * effectively removing it from the tree. -+ * -+ * This function will alter only the bytes in the blob which contain -+ * the node and its properties and subnodes, and will not alter or -+ * move any other part of the tree. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_nop_node(void *fdt, int nodeoffset); -+ -+/**********************************************************************/ -+/* Sequential write functions */ -+/**********************************************************************/ -+ -+/* fdt_create_with_flags flags */ -+#define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 -+ /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property -+ * names in the fdt. This can result in faster creation times, but -+ * a larger fdt. */ -+ -+#define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) -+ -+/** -+ * fdt_create_with_flags - begin creation of a new fdt -+ * @buf: pointer to memory allocated where fdt will be created -+ * @bufsize: size of the memory space at fdt -+ * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. -+ * -+ * fdt_create_with_flags() begins the process of creating a new fdt with -+ * the sequential write interface. -+ * -+ * fdt creation process must end with fdt_finished() to produce a valid fdt. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt -+ * -FDT_ERR_BADFLAGS, flags is not valid -+ */ -+int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); -+ -+/** -+ * fdt_create - begin creation of a new fdt -+ * @buf: pointer to memory allocated where fdt will be created -+ * @bufsize: size of the memory space at fdt -+ * -+ * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt -+ */ -+int fdt_create(void *buf, int bufsize); -+ -+int fdt_resize(void *fdt, void *buf, int bufsize); -+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); -+int fdt_finish_reservemap(void *fdt); -+int fdt_begin_node(void *fdt, const char *name); -+int fdt_property(void *fdt, const char *name, const void *val, int len); -+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) -+{ -+ fdt32_t tmp = cpu_to_fdt32(val); -+ return fdt_property(fdt, name, &tmp, sizeof(tmp)); -+} -+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) -+{ -+ fdt64_t tmp = cpu_to_fdt64(val); -+ return fdt_property(fdt, name, &tmp, sizeof(tmp)); -+} -+ -+#ifndef SWIG /* Not available in Python */ -+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) -+{ -+ return fdt_property_u32(fdt, name, val); -+} -+#endif -+ -+/** -+ * 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); -+int fdt_finish(void *fdt); -+ -+/**********************************************************************/ -+/* Read-write functions */ -+/**********************************************************************/ -+ -+int fdt_create_empty_tree(void *buf, int bufsize); -+int fdt_open_into(const void *fdt, void *buf, int bufsize); -+int fdt_pack(void *fdt); -+ -+/** -+ * fdt_add_mem_rsv - add one memory reserve map entry -+ * @fdt: pointer to the device tree blob -+ * @address: 64-bit start address of the reserve map entry -+ * @size: 64-bit size of the reserved region -+ * -+ * Adds a reserve map entry to the given blob reserving a region at -+ * address address of length size. -+ * -+ * This function will insert data into the reserve map and will -+ * therefore change the indexes of some entries in the table. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to -+ * contain the new reservation entry -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); -+ -+/** -+ * fdt_del_mem_rsv - remove a memory reserve map entry -+ * @fdt: pointer to the device tree blob -+ * @n: entry to remove -+ * -+ * fdt_del_mem_rsv() removes the n-th memory reserve map entry from -+ * the blob. -+ * -+ * This function will delete data from the reservation table and will -+ * therefore change the indexes of some entries in the table. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there -+ * are less than n+1 reserve map entries) -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_del_mem_rsv(void *fdt, int n); -+ -+/** -+ * fdt_set_name - change the name of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of a node -+ * @name: name to give the node -+ * -+ * fdt_set_name() replaces the name (including unit address, if any) -+ * of the given node with the given string. NOTE: this function can't -+ * efficiently check if the new name is unique amongst the given -+ * node's siblings; results are undefined if this function is invoked -+ * with a name equal to one of the given node's siblings. -+ * -+ * 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 name -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+int fdt_set_name(void *fdt, int nodeoffset, const char *name); -+ -+/** -+ * fdt_setprop - create or change 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 -+ * @val: pointer to data to set the property value to -+ * @len: length of the property value -+ * -+ * fdt_setprop() sets the value of the named property in the given -+ * node to the given value and length, creating the 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 -+ */ -+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 -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: 32-bit integer value for the property (native endian) -+ * -+ * fdt_setprop_u32() sets the value of the named property in the given -+ * node to the given 32-bit integer value (converting to big-endian if -+ * necessary), or creates a new property with that value 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 -+ */ -+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, -+ uint32_t val) -+{ -+ fdt32_t tmp = cpu_to_fdt32(val); -+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_setprop_u64 - set a property to a 64-bit integer -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: 64-bit integer value for the property (native endian) -+ * -+ * fdt_setprop_u64() sets the value of the named property in the given -+ * node to the given 64-bit integer value (converting to big-endian if -+ * necessary), or creates a new property with that value 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 -+ */ -+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, -+ uint64_t val) -+{ -+ fdt64_t tmp = cpu_to_fdt64(val); -+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_setprop_cell - set a property to a single cell value -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @val: 32-bit integer value for the property (native endian) -+ * -+ * This is an alternative name for fdt_setprop_u32() -+ * -+ * Return: 0 on success, negative libfdt error value otherwise. -+ */ -+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, -+ uint32_t val) -+{ -+ return fdt_setprop_u32(fdt, nodeoffset, name, val); -+} -+ -+/** -+ * fdt_setprop_string - set a property to a string value -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @str: string value for the property -+ * -+ * fdt_setprop_string() sets the value of the named property in the -+ * given node to the given string value (using the length of the -+ * string to determine the new length of the property), or creates a -+ * new property with that value 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_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 -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to append to -+ * @val: pointer to data to append to the property value -+ * @len: length of the data to append to the property value -+ * -+ * fdt_appendprop() appends the value to the named property in the -+ * given node, creating the property if it does not already exist. -+ * -+ * This function may insert data into 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_appendprop(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len); -+ -+/** -+ * fdt_appendprop_u32 - append a 32-bit integer value to 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 -+ * @val: 32-bit integer value to append to the property (native endian) -+ * -+ * fdt_appendprop_u32() appends the given 32-bit integer value -+ * (converting to big-endian if necessary) to the value of the named -+ * property in the given node, or creates a new property with that -+ * value if it does not already exist. -+ * -+ * This function may insert data into 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 -+ */ -+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, -+ const char *name, uint32_t val) -+{ -+ fdt32_t tmp = cpu_to_fdt32(val); -+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_appendprop_u64 - append a 64-bit integer value to 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 -+ * @val: 64-bit integer value to append to the property (native endian) -+ * -+ * fdt_appendprop_u64() appends the given 64-bit integer value -+ * (converting to big-endian if necessary) to the value of the named -+ * property in the given node, or creates a new property with that -+ * value if it does not already exist. -+ * -+ * This function may insert data into 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 -+ */ -+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, -+ const char *name, uint64_t val) -+{ -+ fdt64_t tmp = cpu_to_fdt64(val); -+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); -+} -+ -+/** -+ * fdt_appendprop_cell - append a single cell value to 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 -+ * @val: 32-bit integer value to append to the property (native endian) -+ * -+ * This is an alternative name for fdt_appendprop_u32() -+ * -+ * Return: 0 on success, negative libfdt error value otherwise. -+ */ -+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, -+ const char *name, uint32_t val) -+{ -+ return fdt_appendprop_u32(fdt, nodeoffset, name, val); -+} -+ -+/** -+ * fdt_appendprop_string - append a string to 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 -+ * @str: string value to append to the property -+ * -+ * fdt_appendprop_string() appends the given string to the value of -+ * the named property in the given node, or creates a new property -+ * with that value if it does not already exist. -+ * -+ * This function may insert data into 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_appendprop_string(fdt, nodeoffset, name, str) \ -+ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) -+ -+/** -+ * fdt_appendprop_addrrange - append a address range property -+ * @fdt: pointer to the device tree blob -+ * @parent: offset of the parent node -+ * @nodeoffset: offset of the node to add a property at -+ * @name: name of property -+ * @addr: start address of a given range -+ * @size: size of a given range -+ * -+ * fdt_appendprop_addrrange() appends an address range value (start -+ * address and size) to the value of the named property in the given -+ * node, or creates a new property with that value if it does not -+ * already exist. -+ * If "name" is not specified, a default "reg" is used. -+ * Cell sizes are determined by parent's #address-cells and #size-cells. -+ * -+ * This function may insert data into the blob, and will therefore -+ * change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #address-cells property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size -+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to -+ * contain a new property -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, -+ const char *name, uint64_t addr, uint64_t size); -+ -+/** -+ * fdt_delprop - delete a property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to nop -+ * @name: name of the property to nop -+ * -+ * fdt_del_property() will delete the given property. -+ * -+ * This function will delete data from the blob, and will therefore -+ * change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOTFOUND, node does not have the named property -+ * -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_TRUNCATED, standard meanings -+ */ -+int fdt_delprop(void *fdt, int nodeoffset, const char *name); -+ -+/** -+ * fdt_add_subnode_namelen - creates a new node based on substring -+ * @fdt: pointer to the device tree blob -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to create -+ * @namelen: number of characters of name to consider -+ * -+ * Identical to fdt_add_subnode(), but use only the first @namelen -+ * characters of @name as the name of the new node. This is useful for -+ * creating subnodes based on a portion of a larger string, such as a -+ * full path. -+ * -+ * Return: structure block offset of the created subnode (>=0), -+ * negative libfdt error value otherwise -+ */ -+#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 -+ * @fdt: pointer to the device tree blob -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to locate -+ * -+ * fdt_add_subnode() creates a new node as a subnode of the node at -+ * structure block offset parentoffset, with the given name (which -+ * should include the unit address, if any). -+ * -+ * This function will insert data into the blob, and will therefore -+ * change the offsets of some existing nodes. -+ * -+ * returns: -+ * 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_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 -+ * blob to contain the new node -+ * -FDT_ERR_NOSPACE -+ * -FDT_ERR_BADLAYOUT -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_add_subnode(void *fdt, int parentoffset, const char *name); -+ -+/** -+ * fdt_del_node - delete a node (subtree) -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node to nop -+ * -+ * fdt_del_node() will remove the given node, including all its -+ * subnodes if any, from the blob. -+ * -+ * This function will delete data from the blob, and will therefore -+ * change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -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_TRUNCATED, standard meanings -+ */ -+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); -+ -+/** -+ * fdt_overlay_target_offset - retrieves the offset of a fragment's target -+ * @fdt: Base device tree blob -+ * @fdto: Device tree overlay blob -+ * @fragment_offset: node offset of the fragment in the overlay -+ * @pathp: pointer which receives the path of the target (or NULL) -+ * -+ * fdt_overlay_target_offset() retrieves the target offset in the base -+ * device tree of a fragment, no matter how the actual targeting is -+ * done (through a phandle or a path) -+ * -+ * returns: -+ * the targeted node offset in the base device tree -+ * Negative error code on error -+ */ -+int fdt_overlay_target_offset(const void *fdt, const void *fdto, -+ int fragment_offset, char const **pathp); -+ -+/**********************************************************************/ -+/* Debugging / informational functions */ -+/**********************************************************************/ -+ -+const char *fdt_strerror(int errval); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* LIBFDT_H */ -diff --git a/include/libfdt_env.h b/include/libfdt_env.h -new file mode 100644 -index 0000000..51b31d1 ---- /dev/null -+++ b/include/libfdt_env.h -@@ -0,0 +1,95 @@ -+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ -+#ifndef LIBFDT_ENV_H -+#define LIBFDT_ENV_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * Copyright 2012 Kim Phillips, Freescale Semiconductor. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __CHECKER__ -+#define FDT_FORCE __attribute__((force)) -+#define FDT_BITWISE __attribute__((bitwise)) -+#else -+#define FDT_FORCE -+#define FDT_BITWISE -+#endif -+ -+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)) -+#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \ -+ (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3)) -+#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \ -+ (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \ -+ (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \ -+ (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7)) -+ -+static inline uint16_t fdt16_to_cpu(fdt16_t x) -+{ -+ return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); -+} -+static inline fdt16_t cpu_to_fdt16(uint16_t x) -+{ -+ return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); -+} -+ -+static inline uint32_t fdt32_to_cpu(fdt32_t x) -+{ -+ return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); -+} -+static inline fdt32_t cpu_to_fdt32(uint32_t x) -+{ -+ return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); -+} -+ -+static inline uint64_t fdt64_to_cpu(fdt64_t x) -+{ -+ return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); -+} -+static inline fdt64_t cpu_to_fdt64(uint64_t 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 -+ -+#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/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0011-common-Add-essential-libc-functions.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0011-common-Add-essential-libc-functions.patch deleted file mode 100644 index b7726f5175..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0011-common-Add-essential-libc-functions.patch +++ /dev/null @@ -1,101 +0,0 @@ -From e2eff4f80e65cb3fcbe6345b5376a6bf7de7e2cc Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 28 Dec 2021 17:28:25 +0800 -Subject: [PATCH] common: Add essential libc functions - -The libfdt uses some of the libc functions, e.g. memcmp, memmove, -strlen .etc. Add them in lib.c. - -The code is copied from TF-A (v2.5) [1] project, which is under the -terms of BSD license. It is the same with boot-wrapper. - -[1]: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git - -Issue-Id: SCM-3814 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: If3b55b00afa8694c7522df989a41e0b38eda1d38 ---- - common/lib.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 70 insertions(+), 1 deletion(-) - -diff --git a/common/lib.c b/common/lib.c -index fcf5f69..0be1c4a 100644 ---- a/common/lib.c -+++ b/common/lib.c -@@ -32,4 +32,73 @@ void *memset(void *s, int c, size_t n) - return s; - } - --/* TODO: memmove and memcmp could also be called */ -+int memcmp(const void *s1, const void *s2, size_t len) -+{ -+ const unsigned char *s = s1; -+ const unsigned char *d = s2; -+ unsigned char sc; -+ unsigned char dc; -+ -+ while (len--) { -+ sc = *s++; -+ dc = *d++; -+ if (sc - dc) -+ return (sc - dc); -+ } -+ -+ return 0; -+} -+ -+void *memmove(void *dst, const void *src, size_t len) -+{ -+ if ((size_t)dst - (size_t)src >= len) { -+ /* destination not in source data, so can safely use memcpy */ -+ return memcpy(dst, src, len); -+ } else { -+ /* copy backwards... */ -+ const char *end = dst; -+ const char *s = (const char *)src + len; -+ char *d = (char *)dst + len; -+ while (d != end) -+ *--d = *--s; -+ } -+ return dst; -+} -+ -+void *memchr(const void *src, int c, size_t len) -+{ -+ const unsigned char *s = src; -+ -+ while (len--) { -+ if (*s == (unsigned char)c) -+ return (void *) s; -+ s++; -+ } -+ -+ return NULL; -+} -+ -+char *strrchr(const char *p, int ch) -+{ -+ char *save; -+ char c; -+ -+ c = ch; -+ for (save = NULL;; ++p) { -+ if (*p == c) -+ save = (char *)p; -+ if (*p == '\0') -+ return (save); -+ } -+ /* NOTREACHED */ -+} -+ -+size_t strlen(const char *s) -+{ -+ const char *cursor = s; -+ -+ while (*cursor) -+ cursor++; -+ -+ return cursor - s; -+} diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0012-Makefile-Add-the-libfdt-to-the-Makefile-system.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0012-Makefile-Add-the-libfdt-to-the-Makefile-system.patch deleted file mode 100644 index b77ab3e27b..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0012-Makefile-Add-the-libfdt-to-the-Makefile-system.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f4d5cf4c3424598a2b3bb391717313b70c79ea28 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 28 Dec 2021 17:42:48 +0800 -Subject: [PATCH] Makefile: Add the libfdt to the Makefile system - -Add the libfdt into Makefile system. The libfdt uses const value and -thus gcc will enable the stack guard. The stack guard will fail the -compile. Add -fno-stack-protector to fix it. - -Issue-Id: SCM-3814 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I472bc28cdc5cde3b22461a4b7d7a3752ae382b4b ---- - Makefile.am | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index fc66662..ab2c3a9 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -36,6 +36,9 @@ PSCI_CPU_OFF := 0x84000002 - COMMON_SRC := common/ - COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o - -+LIBFDT_SRC := common/libfdt/ -+LIBFDT_OBJS := fdt.o fdt_ro.o fdt_rw.o -+ - ARCH_OBJ := boot.o stack.o utils.o - - if BOOTWRAPPER_32 -@@ -127,11 +130,12 @@ CFLAGS += -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/ - CFLAGS += -Wall -fomit-frame-pointer - CFLAGS += -ffreestanding -nostdlib - CFLAGS += -fno-stack-protector -+CFLAGS += -fno-stack-protector - CFLAGS += -ffunction-sections -fdata-sections - CFLAGS += -fno-pic -fno-pie - LDFLAGS += --gc-sections - --OBJ := $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ)) -+OBJ := $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ)) $(addprefix $(LIBFDT_SRC),$(LIBFDT_OBJS)) - - # Don't lookup all prerequisites in $(top_srcdir), only the source files. When - # building outside the source tree $(ARCH_SRC) needs to be created. -@@ -152,10 +156,13 @@ $(ARCH_SRC): - $(COMMON_SRC): - $(MKDIR_P) $@ - -+$(LIBFDT_SRC): -+ $(MKDIR_P) $@ -+ - %.o: %.S Makefile | $(ARCH_SRC) - $(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $< - --%.o: %.c Makefile | $(COMMON_SRC) -+%.o: %.c Makefile | $(COMMON_SRC) $(LIBFDT_SRC) - $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $< - - model.lds: $(LD_SCRIPT) Makefile diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0013-platform-Add-print_hex-func.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0013-platform-Add-print_hex-func.patch deleted file mode 100644 index 2346109c02..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0013-platform-Add-print_hex-func.patch +++ /dev/null @@ -1,67 +0,0 @@ -From f0ece5e8cac761a76a86df7204bae7c6ef09215f Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Wed, 29 Dec 2021 10:50:21 +0800 -Subject: [PATCH] platform: Add print_hex func - -Refine the print functions, and add a new print_hex func to print hex -numbers. - -Issue-Id: SCM-3814 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: Ic960345d9ef0b41d81d30c4a4dbd9c31139907c4 ---- - common/platform.c | 33 +++++++++++++++++++++++++-------- - 1 file changed, 25 insertions(+), 8 deletions(-) - -diff --git a/common/platform.c b/common/platform.c -index d11f568..8269392 100644 ---- a/common/platform.c -+++ b/common/platform.c -@@ -30,20 +30,37 @@ - #define V2M_SYS(reg) ((void *)SYSREGS_BASE + V2M_SYS_##reg) - #endif - --static void print_string(const char *str) -+static void print_char(const char c) - { - uint32_t flags; -+ do { -+ flags = raw_readl(PL011(UARTFR)); -+ } while (flags & PL011_UARTFR_FIFO_FULL); - -+ raw_writel(c, PL011(UARTDR)); -+ -+ do { -+ flags = raw_readl(PL011(UARTFR)); -+ } while (flags & PL011_UARTFR_BUSY); -+} -+ -+void print_string(const char *str) -+{ - while (*str) { -- do -- flags = raw_readl(PL011(UARTFR)); -- while (flags & PL011_UARTFR_FIFO_FULL); -+ print_char(*str++); -+ } -+} - -- raw_writel(*str++, PL011(UARTDR)); -+#define HEX_CHARS_PER_INT (2 * sizeof(int)) -+ -+void print_hex(unsigned int val) -+{ - -- do -- flags = raw_readl(PL011(UARTFR)); -- while (flags & PL011_UARTFR_BUSY); -+ const char hex_chars[16] = "0123456789abcdef"; -+ int i; -+ for (i = HEX_CHARS_PER_INT - 1; i >= 0; i--) { -+ int v = (val >> (4 * i)) & 0xf; -+ print_char(hex_chars[v]); - } - } - diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0014-common-Add-mem-usage-to-memreserve.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0014-common-Add-mem-usage-to-memreserve.patch deleted file mode 100644 index f4ea89c609..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0014-common-Add-mem-usage-to-memreserve.patch +++ /dev/null @@ -1,96 +0,0 @@ -From f4704146e1af9f6e0a2220db6b39a328c813fac1 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Wed, 19 Jan 2022 16:19:02 +0800 -Subject: [PATCH] common: Add mem usage to /memreserve/ - -Set /memreserve/ to prevent next boot stages from overrding PSCI -services with libfdt. - -Issue-Id: SCM-3815 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I2ea80cdf736a910fa2c3deb622e21d50f04be960 ---- - Makefile.am | 2 +- - common/boot.c | 1 + - common/device_tree.c | 34 ++++++++++++++++++++++++++++++++++ - include/boot.h | 1 + - 4 files changed, 37 insertions(+), 1 deletion(-) - create mode 100644 common/device_tree.c - -diff --git a/Makefile.am b/Makefile.am -index ab2c3a9..e905602 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -34,7 +34,7 @@ endif - PSCI_CPU_OFF := 0x84000002 - - COMMON_SRC := common/ --COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o -+COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o device_tree.o - - LIBFDT_SRC := common/libfdt/ - LIBFDT_OBJS := fdt.o fdt_ro.o fdt_rw.o -diff --git a/common/boot.c b/common/boot.c -index c74d34c..ee2bea0 100644 ---- a/common/boot.c -+++ b/common/boot.c -@@ -63,6 +63,7 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox, - { - if (cpu == 0) { - init_platform(); -+ dt_add_memreserve(); - - *mbox = (unsigned long)&entrypoint; - sevl(); -diff --git a/common/device_tree.c b/common/device_tree.c -new file mode 100644 -index 0000000..4d0876c ---- /dev/null -+++ b/common/device_tree.c -@@ -0,0 +1,34 @@ -+/* -+ * device_tree.c - Basic device tree node handler -+ * -+ * Copyright (C) 2021 ARM Limited. All rights reserved. -+ * -+ * Use of this source code is governed by a BSD-style license that can be -+ * found in the LICENSE.txt file. -+ */ -+#include -+ -+extern unsigned long dtb; -+extern char firmware_start[], firmware_end[]; -+ -+extern void print_string(const char *str); -+ -+static void *blob; -+ -+ -+void dt_add_memreserve(void) -+{ -+ int ret; -+ -+ blob = (void*)&dtb; -+ print_string("Add /memreserve/\n\r"); -+ -+ fdt_open_into(blob, blob, fdt_totalsize(blob) + -+ sizeof(struct fdt_reserve_entry)); -+ ret = fdt_add_mem_rsv(blob, (uint64_t)firmware_start, -+ (uint64_t)(firmware_end - firmware_start)); -+ -+ if(ret < 0) { -+ print_string("reserve mem add err\n\r"); -+ } -+} -diff --git a/include/boot.h b/include/boot.h -index d75e013..c3e2ec1 100644 ---- a/include/boot.h -+++ b/include/boot.h -@@ -16,4 +16,5 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry); - void __noreturn first_spin(unsigned int cpu, unsigned long *mbox, - unsigned long invalid_addr); - -+void dt_add_memreserve(void); - #endif diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0015-boot-Add-the-enable-keep-el-compile-option.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0015-boot-Add-the-enable-keep-el-compile-option.patch deleted file mode 100644 index 7d59e5fc3b..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0015-boot-Add-the-enable-keep-el-compile-option.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 5995f83592aea874f5b423538e36675e2204582b Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 4 Jan 2022 17:01:55 +0800 -Subject: [PATCH] boot: Add the --enable-keep-el compile option - -Add --enable-keep-el compile option to enable boot-wrapper booting next -stage at EL2. -The Armv8R AArch64 boots at EL2. If the next stage requires EL2 booting, -the boot-wrapper should not drop to EL1. -Currently, this option only works for Armv8R AArch64. Also, to work with -Linux PSCI, this option will cause secondary cores booting at EL1. - -Issue-Id: SCM-3813 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I3ba9c87cf0b59d163ca433f74c9e3a46e5ca2c63 ---- - Makefile.am | 4 ++++ - arch/aarch64/boot.S | 6 +++++- - common/psci.c | 6 ++++++ - configure.ac | 5 +++++ - 4 files changed, 20 insertions(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index e905602..6604baa 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -33,6 +33,10 @@ PSCI_CPU_ON := 0xc4000003 - endif - PSCI_CPU_OFF := 0x84000002 - -+if KEEP_EL -+DEFINES += -DKEEP_EL -+endif -+ - COMMON_SRC := common/ - COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o device_tree.o - -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index 27b1139..c079d22 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -254,7 +254,11 @@ el2_init: - msr cnthctl_el2, x0 - isb - -+#ifdef KEEP_EL -+ mov w0, #SPSR_KERNEL -+#else - mov w0, #SPSR_KERNEL_EL1 -+#endif - ldr x1, =spsr_to_elx - str w0, [x1] - // fall through -@@ -334,5 +338,5 @@ ASM_FUNC(jump_kernel) - .align 3 - flag_keep_el: - .long 0 --spsr_to_elx: -+ASM_DATA(spsr_to_elx) - .long 0 -diff --git a/common/psci.c b/common/psci.c -index a0e8700..945780b 100644 ---- a/common/psci.c -+++ b/common/psci.c -@@ -18,6 +18,8 @@ - #error "No MPIDRs provided" - #endif - -+extern unsigned int spsr_to_elx; -+ - static unsigned long branch_table[NR_CPUS]; - - bakery_ticket_t branch_table_lock[NR_CPUS]; -@@ -44,6 +46,10 @@ static int psci_cpu_on(unsigned long target_mpidr, unsigned long address) - ret = psci_store_address(cpu, address); - bakery_unlock(branch_table_lock, this_cpu); - -+#ifdef KEEP_EL -+ spsr_to_elx = SPSR_KERNEL_EL1; -+#endif -+ - return ret; - } - -diff --git a/configure.ac b/configure.ac -index 53e51be..0e07db3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -25,6 +25,11 @@ AS_IF([test "x$BOOTWRAPPER_ES" = x32 -a "x$KERNEL_ES" != x32], - [AC_MSG_ERROR([a 32-bit boot-wrapper cannot launch a 64-bit kernel])] - ) - -+AC_ARG_ENABLE([keep-el], -+ AC_HELP_STRING([--enable-keep-el], [keep exception level when start kernel]), -+ [KEEP_EL=yes], [KEEP_EL=no]) -+AM_CONDITIONAL([KEEP_EL], [test "x$KEEP_EL" = xyes]) -+ - # Allow a user to pass --with-kernel-dir - AC_ARG_WITH([kernel-dir], - AS_HELP_STRING([--with-kernel-dir], [specify the root Linux kernel build directory (required)]), diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0016-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0016-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch deleted file mode 100644 index e93a300fb7..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0016-Makefile-Change-COUNTER_FREQ-to-100-MHz.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0c0695cd3160ccdb95bae29b7668918015c0b6aa Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Tue, 1 Feb 2022 11:28:46 +0000 -Subject: [PATCH] Makefile: Change COUNTER_FREQ to 100 MHz - -Older Arm Fast Models (AEM < RevC) had a base frequency of 24 MHz. but -the RevC base models use 100 MHz. There is not a robust method of -determining the configured base frequency at runtime, so update -COUNTER_FREQ to be 100 MHz. - -Issue-Id: SCM-3871 -Upstream-Status: Pending -Signed-off-by: Peter Hoyes -Change-Id: Ia9ad0f8ee488d1a887791f1fa1d8f3bf9c5887fd ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 6604baa..cc6504e 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -13,7 +13,7 @@ SCRIPT_DIR := $(top_srcdir)/scripts - PHYS_OFFSET := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findmem.pl $(KERNEL_DTB)) - UART_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011') - SYSREGS_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg' 2> /dev/null) --COUNTER_FREQ := 24000000 -+COUNTER_FREQ := 100000000 - - CPU_IDS := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findcpuids.pl $(KERNEL_DTB)) - NR_CPUS := $(shell echo $(CPU_IDS) | tr ',' ' ' | wc -w) diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0017-PSCI-Apply-flush-cache-after-setting-branch_data.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0017-PSCI-Apply-flush-cache-after-setting-branch_data.patch deleted file mode 100644 index b63d8d1d3f..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0017-PSCI-Apply-flush-cache-after-setting-branch_data.patch +++ /dev/null @@ -1,49 +0,0 @@ -From fa73d885be85eee4369b292ec601e7b024a68807 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 2 Nov 2021 10:48:39 +0800 -Subject: [PATCH] PSCI: Apply flush cache after setting branch_data - -For v8-R64, Hypervisor calls boot-wrapper's PSCI service using simple -function call (instead of hvc). - -In this case, hypervisor's main core has enabled MPU and cache, but -the secondary cores which are spinning have not enabled cache. -That means if the main core set the branch_data to 1 to boot other -cores, the secondary cores cannot see the change of branch_data and -also cannot break the spin. - -Thus, the PSCI service in boot-wrapper needs a cache flush after -setting branch_data in order to let other cores see the change. - -Issue-ID: SCM-3816 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: Ifc282091c54d8fb2ffdb8cfa7fd3ffc1f4be717e ---- - common/psci.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/common/psci.c b/common/psci.c -index 945780b..6efc695 100644 ---- a/common/psci.c -+++ b/common/psci.c -@@ -24,12 +24,18 @@ static unsigned long branch_table[NR_CPUS]; - - bakery_ticket_t branch_table_lock[NR_CPUS]; - -+static inline void flush_per_cpu_data(void *data) -+{ -+ asm volatile ("dc cvac, %0" : : "r" (data)); -+} -+ - static int psci_store_address(unsigned int cpu, unsigned long address) - { - if (branch_table[cpu] != PSCI_ADDR_INVALID) - return PSCI_RET_ALREADY_ON; - - branch_table[cpu] = address; -+ flush_per_cpu_data((void*)&(branch_table[cpu])); - return PSCI_RET_SUCCESS; - } - diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0018-PSCI-Add-function-call-entry-point.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0018-PSCI-Add-function-call-entry-point.patch deleted file mode 100644 index dd2b96537f..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0018-PSCI-Add-function-call-entry-point.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 9da48e3433b919868650cd60e28827273a42c63b Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 25 Jan 2022 14:56:36 +0800 -Subject: [PATCH] PSCI: Add function call entry point - -The max exception level of Armv8R AArch64 is EL2, which means it has no -exclusive EL for firmware. That is, firmware and hypervisors have to share -the EL2. Also, hypervisors cannot call firmware services via a 'smc' -instruction. Thus, boot-wrapper has to provide a function entry point -for Armv8R AArch64. - -Issue-Id: SCM-3816 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I06ec8e50298603155c6d8ae2330e71db2f111182 ---- - common/psci.c | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/common/psci.c b/common/psci.c -index 6efc695..8fdefb5 100644 ---- a/common/psci.c -+++ b/common/psci.c -@@ -20,6 +20,8 @@ - - extern unsigned int spsr_to_elx; - -+unsigned long flag_from_smc_fn[NR_CPUS]; -+ - static unsigned long branch_table[NR_CPUS]; - - bakery_ticket_t branch_table_lock[NR_CPUS]; -@@ -49,12 +51,14 @@ static int psci_cpu_on(unsigned long target_mpidr, unsigned long address) - return PSCI_RET_INVALID_PARAMETERS; - - bakery_lock(branch_table_lock, this_cpu); -- ret = psci_store_address(cpu, address); -- bakery_unlock(branch_table_lock, this_cpu); -- - #ifdef KEEP_EL -- spsr_to_elx = SPSR_KERNEL_EL1; -+ if (!flag_from_smc_fn[this_cpu]) { -+ spsr_to_elx = SPSR_KERNEL_EL1; -+ flush_per_cpu_data((void*)&(spsr_to_elx)); -+ } - #endif -+ ret = psci_store_address(cpu, address); -+ bakery_unlock(branch_table_lock, this_cpu); - - return ret; - } -@@ -90,6 +94,18 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2) - } - } - -+long smc_fn_entry(unsigned long fid, unsigned long arg1, unsigned long arg2) -+{ -+ long ret; -+ unsigned int this_cpu = this_cpu_logical_id(); -+ -+ flag_from_smc_fn[this_cpu] = 1; -+ ret = psci_call(fid, arg1, arg2); -+ flag_from_smc_fn[this_cpu] = 0; -+ -+ return ret; -+} -+ - void __noreturn psci_first_spin(unsigned int cpu) - { - if (cpu == MPIDR_INVALID) diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0019-lds-Rearrange-and-mark-the-sections.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0019-lds-Rearrange-and-mark-the-sections.patch deleted file mode 100644 index c0d1fcbbb8..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0019-lds-Rearrange-and-mark-the-sections.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7c5e40d9f8699a55ac2187c035429c643e6d0ef0 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Tue, 2 Nov 2021 15:10:28 +0800 -Subject: [PATCH] lds: Rearrange and mark the sections - -To make it possible for the next stage to protect sections with MPU, -boot-wrapper needs to provide the text and data section information. -By rearranging the .data .rodata and .vector sections, all sections -can be split into 2 big sections: - - RO and Executable - - RW and Non-Executable -Add firmware_data to mark the boundry, thus: -firmware_start to firmware_data - 1 indicates RO and Executable section, -firmware_data to firmware_end - 1 indicates RW and Non-Executable -section. - -Also, the firmware_data and firmware_end should align with 64 bytes, -since Armv8R AArch64 MPU requires it. - -Issue-ID: SCM-3816 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I55342aa7492f2c7b5c16ab9a6472c8cb45cff8fd ---- - model.lds.S | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/model.lds.S b/model.lds.S -index ab98ddf..85451f9 100644 ---- a/model.lds.S -+++ b/model.lds.S -@@ -63,12 +63,16 @@ SECTIONS - } - #endif - -+#define FIRMWARE_ALIGN . = ALIGN(1 << 6) - .boot PHYS_OFFSET: { - PROVIDE(firmware_start = .); - *(.init) - *(.text*) -- *(.data* .rodata* .bss* COMMON) - *(.vectors) -+ *(.rodata*) -+ FIRMWARE_ALIGN; -+ PROVIDE(firmware_data = .); -+ *(.data* .bss* COMMON) - *(.stack) - PROVIDE(etext = .); - } -@@ -77,6 +81,7 @@ SECTIONS - mbox = .; - QUAD(0x0) - } -+ FIRMWARE_ALIGN; - PROVIDE(firmware_end = .); - - ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!") diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0020-common-Provide-firmware-info-using-libfdt.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0020-common-Provide-firmware-info-using-libfdt.patch deleted file mode 100644 index 1573be05c4..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0020-common-Provide-firmware-info-using-libfdt.patch +++ /dev/null @@ -1,342 +0,0 @@ -From 3c1140c29c39561848056fb4b9a03042b00279f3 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Wed, 29 Dec 2021 15:17:38 +0800 -Subject: [PATCH] common: Provide firmware info using libfdt - -Boot-wrapper uses libfdt to provide more info in device tree. -We add a new node to include those new firmware relevant infomation. -The new node defined as follows: - fw-shared-info { - compatible = "firmware,shared_info"; - - #address-cells = <0x02>; - #size-cells = <0x02>; - - version = "1.0"; - regions = ; - regions-permission = "RX", "R", "RWX", "RW"; - regions-cache = "Cache", "NCache", "Cache", "Device" - - function_entry = ; - }; -The node path is /fw-shared-info. -For boot-wrapper, in real case, it will be: - fw-shared-info { - compatible = "firmware,shared_info"; - - #address-cells = <0x02>; - #size-cells = <0x02>; - - version = "1.0"; - regions = <0x0 firmware_start 0x0 firmware_code_size - 0x0 firmware_data 0x0 firmware_data_size>; - regions-permission = "RX", "RW"; - regions-cache = "Cache", "Cache"; - - function_entry = <0x0 smc_fn_entry>; - }; - -Issue-Id: SCM-3816 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: I6ebc59ce2bd3939b0fe066720d57821eaa1bed27 ---- - common/device_tree.c | 271 ++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 270 insertions(+), 1 deletion(-) - -diff --git a/common/device_tree.c b/common/device_tree.c -index 4d0876c..7f7befc 100644 ---- a/common/device_tree.c -+++ b/common/device_tree.c -@@ -8,13 +8,225 @@ - */ - #include - -+#define DEVICE_TREE_DEBUG 1 -+ -+#define FW_NODE_NAME "/fw-shared-info" -+#define FW_COMPAT "firmware,shared_info" -+#define FW_INFO_VER "1.0" -+ -+#ifdef BOOTWRAPPER_32 -+#define CELL_NUM 1 -+#define VAL_TYPE uint32_t -+#else -+#define CELL_NUM 2 -+#define VAL_TYPE uint64_t -+#endif -+ -+#define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) -+ - extern unsigned long dtb; --extern char firmware_start[], firmware_end[]; -+extern char firmware_start[], firmware_data[], firmware_end[]; -+ -+extern long smc_fn_entry(unsigned long, unsigned long, unsigned long); - - extern void print_string(const char *str); -+extern void print_hex(unsigned int val); - - static void *blob; - -+static char *realloc_node(char *fdt, const char *name) -+{ -+ int delta; -+ int new_sz; -+ /* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */ -+ delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1) -+ + FDT_TAGSIZE; -+ new_sz = fdt_totalsize(fdt) + delta; -+ fdt_open_into(fdt, fdt, new_sz); -+ return fdt; -+} -+ -+static int create_node(const char *node_name) -+{ -+ int node = 0; -+ char *p; -+ -+ p = strrchr(node_name, '/'); -+ if (!p) { -+ print_string("node name without '/'\r\n"); -+ return -1; -+ } -+ *p = '\0'; -+ -+ blob = realloc_node(blob, p + 1); -+ -+ if (p > node_name) { -+ node = fdt_path_offset(blob, node_name); -+ if (node < 0) { -+ print_string("no node name\r\n"); -+ return -1; -+ } -+ } -+ -+ node = fdt_add_subnode(blob, node, p + 1); -+ if (node < 0) { -+ print_string("add subnode err\r\n"); -+ return -1; -+ } -+ -+ return node; -+} -+ -+static int dt_create_fw_node(void) { -+ int fw_node; -+ -+ fw_node = fdt_path_offset(blob, FW_NODE_NAME); -+ -+ if(fw_node < 0) { -+ fw_node = create_node(FW_NODE_NAME); -+ } -+ -+ return fw_node; -+} -+ -+static char *realloc_property(char *fdt, int nodeoffset, const char *name, -+ int newlen) -+{ -+ int delta = 0; -+ int oldlen = 0; -+ int new_sz; -+ -+ if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) -+ delta = sizeof(struct fdt_property) + strlen(name) + 1; -+ -+ if (newlen > oldlen) -+ delta += ALIGN(newlen) - ALIGN(oldlen); -+ -+ new_sz = fdt_totalsize(fdt) + delta; -+ fdt_open_into(fdt, fdt, new_sz); -+ return fdt; -+} -+ -+static void dt_set_prop(int node, char *property, void *buf, int len) -+{ -+ int err; -+ -+ 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); -+ } -+ if (err) { -+ print_string("fdt error\n\r"); -+ } -+} -+ -+static void dt_set_prop_u32(int node, char *property, uint32_t val) -+{ -+ fdt32_t fdt_val = cpu_to_fdt32(val); -+ int len = sizeof(fdt32_t); -+ -+ dt_set_prop(node, property, (void*)&fdt_val, len); -+} -+ -+static void dt_set_prop_u64(int node, char *property, uint64_t val) -+{ -+ fdt64_t fdt_val = cpu_to_fdt64(val); -+ int len = sizeof(fdt64_t); -+ -+ dt_set_prop(node, property, (void*)&fdt_val, len); -+} -+ -+/* This dt_set_prop_u32_array maybe unused according to the BOOTWRAPPER_32 */ -+__attribute__((unused)) -+static void dt_set_prop_u32_array(int node, char *property, uint32_t *vals, -+ int size) -+{ -+ fdt32_t *fdt_vals = (fdt32_t*)vals; -+ int len = sizeof(fdt32_t) * size; -+ -+ for (int i = 0; i < size; i++) { -+ fdt_vals[i] = cpu_to_fdt32(vals[i]); -+ } -+ -+ dt_set_prop(node, property, (void*)fdt_vals, len); -+} -+ -+static void dt_set_prop_u64_array(int node, char *property, uint64_t *vals, -+ int size) -+{ -+ fdt64_t *fdt_vals = (fdt64_t*)vals; -+ int len = sizeof(fdt64_t) * size; -+ -+ for (int i = 0; i < size; i++) { -+ fdt_vals[i] = cpu_to_fdt64(vals[i]); -+ } -+ -+ dt_set_prop(node, property, (void*)fdt_vals, len); -+} -+ -+#if DEVICE_TREE_DEBUG -+static void dt_dump_string(const void *s, int len) -+{ -+ char *sub = (char*)s; -+ int sublen; -+ while(*sub && ((uint64_t)sub - (uint64_t)s) < len) { -+ sublen = strlen(sub) + 1; -+ print_string(sub); -+ print_string(" "); -+ sub += sublen; -+ } -+ print_string("\n\r"); -+} -+ -+static void dt_dump_fdt32_array(const void *vals, int len) -+{ -+ fdt32_t *fdt_vals = (fdt32_t*)vals; -+ len = len / sizeof(fdt32_t); -+ for (int i = 0; i < len; i++) { -+ print_hex(fdt32_to_cpu(fdt_vals[i])); -+ print_string(" "); -+ } -+ print_string("\n\r"); -+} -+ -+static void dt_dump(int node, char *property, char type) -+{ -+ const void *val; -+ int len; -+ -+ val = fdt_getprop(blob, node, property, &len); -+ print_string(property); -+ print_string(": "); -+ -+ if (type == 's') { -+ /* string type */ -+ dt_dump_string(val, len); -+ return; -+ } -+ -+ /* uint type */ -+ dt_dump_fdt32_array(val, len); -+} -+ -+void dt_dump_all(int node) -+{ -+ if (node >= 0) { -+ print_string(FW_NODE_NAME" info:\r\n"); -+ dt_dump(node, "compatible", 's'); -+ dt_dump(node, "version", 's'); -+ dt_dump(node, "function_entry", 'i'); -+ dt_dump(node, "address-cells", 'i'); -+ dt_dump(node, "size-cells", 'i'); -+ dt_dump(node, "regions", 'i'); -+ dt_dump(node, "regions-permission", 's'); -+ dt_dump(node, "regions-cache", 's'); -+ print_string("\r\n"); -+ } -+} -+#else -+void dt_dump_all(int node) { (void*)node; return; } -+#endif - - void dt_add_memreserve(void) - { -@@ -32,3 +244,60 @@ void dt_add_memreserve(void) - print_string("reserve mem add err\n\r"); - } - } -+ -+void dt_fw_node_init(int enable) -+{ -+ int fw_node; -+ -+ VAL_TYPE regions[] = { -+ /* code region: start, end, ro, x, cachable */ -+ (VAL_TYPE)firmware_start, -+ (VAL_TYPE)(firmware_data - firmware_start), -+ /* data region: start, end, rw, xn, cachable */ -+ (VAL_TYPE)firmware_data, -+ (VAL_TYPE)(firmware_end - firmware_data), -+ }; -+ int regions_num = sizeof(regions) / sizeof(VAL_TYPE); -+ char regions_permission[] = "RX\0RW"; -+ char regions_cache[] = "Cache\0Cache"; -+ -+ if (!enable) -+ return; -+ -+ print_string("Prepare "FW_NODE_NAME" node\n\r"); -+ -+ blob = (void*)&dtb; -+ -+ if(fdt_path_offset(blob, "/psci") < 0) { -+ print_string("/psci node not found\n\r"); -+ return; -+ } -+ -+ fw_node = dt_create_fw_node(); -+ -+ if(fw_node < 0) { -+ print_string(FW_NODE_NAME" node create err\n\r"); -+ } -+ -+ dt_set_prop(fw_node, "compatible", FW_COMPAT, sizeof(FW_COMPAT)); -+ dt_set_prop(fw_node, "version", FW_INFO_VER, sizeof(FW_INFO_VER)); -+ -+ dt_set_prop_u32(fw_node, "address-cells", CELL_NUM); -+ dt_set_prop_u32(fw_node, "size-cells", CELL_NUM); -+ dt_set_prop(fw_node, "regions-permission", regions_permission, -+ sizeof(regions_permission)); -+ dt_set_prop(fw_node, "regions-cache", regions_cache, -+ sizeof(regions_cache)); -+ -+#ifdef BOOTWRAPPER_32 -+ dt_set_prop_u32_array(fw_node, "regions", regions, regions_num); -+ dt_set_prop_u32(fw_node, "function_entry", (VAL_TYPE)smc_fn_entry); -+#else -+ dt_set_prop_u64_array(fw_node, "regions", regions, regions_num); -+ dt_set_prop_u64(fw_node, "function_entry", (VAL_TYPE)smc_fn_entry); -+#endif -+ -+ fdt_pack(blob); -+ -+ dt_dump_all(fw_node); -+} diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0021-boot-Enable-firmware-node-initialization.patch b/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0021-boot-Enable-firmware-node-initialization.patch deleted file mode 100644 index 9b367a7bfb..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/boot-wrapper-aarch64/files/fvp-baser-aemv8r64/0021-boot-Enable-firmware-node-initialization.patch +++ /dev/null @@ -1,95 +0,0 @@ -From b1105e862e8f770fc195bc20e9c64d231dd32f66 Mon Sep 17 00:00:00 2001 -From: Jaxson Han -Date: Wed, 29 Dec 2021 15:33:17 +0800 -Subject: [PATCH] boot: Enable firmware node initialization - -Enable the firmware node initialization, so that the next stage -(hypervisor) could share the EL2 with firmware (boot-wrapper). The next -stage (hypervisor) get the smccc entry point, code/data sections, the -sections attrs and firmware node version and so on. -It is worth noting that this EL2 sharing mechanism is only for Armv8R -AArch64, thus add flag_v8r to record if the arch is Armv8R AArch64. -Enable the firmware node initialization only if it is Armv8R AArch64. -Also, we increase the stack size to 1024 to fix the stack overflow issue -when using the libfdt. - -Add -fno-builtin options to CFLAGS to avoid the issue that the 'memset' -in common/lib.c conflicts with builtin 'memset' function. GCC version ->= 10 will have an incorrect compilation without -fno-builtin; - -Issue-Id: SCM-3816 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Jaxson Han -Change-Id: Ib274485a34d26215595fd0cd737be86610289817 ---- - Makefile.am | 4 ++-- - arch/aarch64/boot.S | 6 ++++++ - common/boot.c | 4 ++++ - 3 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index cc6504e..fbe6b81 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -23,7 +23,7 @@ DEFINES += -DCPU_IDS=$(CPU_IDS) - DEFINES += -DNR_CPUS=$(NR_CPUS) - DEFINES += $(if $(SYSREGS_BASE), -DSYSREGS_BASE=$(SYSREGS_BASE), ) - DEFINES += -DUART_BASE=$(UART_BASE) --DEFINES += -DSTACK_SIZE=256 -+DEFINES += -DSTACK_SIZE=1024 - - if KERNEL_32 - DEFINES += -DKERNEL_32 -@@ -134,7 +134,7 @@ CFLAGS += -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/ - CFLAGS += -Wall -fomit-frame-pointer - CFLAGS += -ffreestanding -nostdlib - CFLAGS += -fno-stack-protector --CFLAGS += -fno-stack-protector -+CFLAGS += -fno-stack-protector -fno-builtin - CFLAGS += -ffunction-sections -fdata-sections - CFLAGS += -fno-pic -fno-pie - LDFLAGS += --gc-sections -diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S -index c079d22..daaa674 100644 ---- a/arch/aarch64/boot.S -+++ b/arch/aarch64/boot.S -@@ -261,6 +261,10 @@ el2_init: - #endif - ldr x1, =spsr_to_elx - str w0, [x1] -+ -+ mov w0, #1 -+ ldr x1, =flag_v8r -+ str w0, [x1] - // fall through - - el_max_init: -@@ -340,3 +344,5 @@ flag_keep_el: - .long 0 - ASM_DATA(spsr_to_elx) - .long 0 -+ASM_DATA(flag_v8r) -+ .long 0 -diff --git a/common/boot.c b/common/boot.c -index ee2bea0..38b2dca 100644 ---- a/common/boot.c -+++ b/common/boot.c -@@ -11,6 +11,9 @@ - - extern unsigned long entrypoint; - extern unsigned long dtb; -+extern unsigned int flag_v8r; -+ -+extern void dt_fw_node_init(int enable); - - void init_platform(void); - -@@ -64,6 +67,7 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox, - if (cpu == 0) { - init_platform(); - dt_add_memreserve(); -+ dt_fw_node_init(flag_v8r == 1); - - *mbox = (unsigned long)&entrypoint; - sevl(); diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-corstone1000.inc b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-corstone1000.inc index 3f66bed55a..ee0713718f 100644 --- a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-corstone1000.inc +++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-corstone1000.inc @@ -38,7 +38,8 @@ EXTRA_OEMAKE:append = " \ NR_OF_IMAGES_IN_FW_BANK=4 \ COT=tbbr \ ARM_ROTPK_LOCATION=devel_rsa \ + ERRATA_A35_855472=1 \ ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \ - BL32=${RECIPE_SYSROOT}/lib/firmware/tee-pager_v2.bin \ + BL32=${RECIPE_SYSROOT}/${nonarch_base_libdir}/firmware/tee-pager_v2.bin \ LOG_LEVEL=50 \ " diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-n1sdp.inc b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-n1sdp.inc index c2fa223cf5..900decc2b9 100644 --- a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-n1sdp.inc +++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-n1sdp.inc @@ -36,6 +36,6 @@ EXTRA_OEMAKE:append = "\ CREATE_KEYS=1 \ ARM_ROTPK_LOCATION="devel_rsa" \ ROT_KEY="${TFA_ROT_KEY}" \ - BL32=${RECIPE_SYSROOT}/lib/firmware/tee-pager_v2.bin \ + BL32=${RECIPE_SYSROOT}/${nonarch_base_libdir}/firmware/tee-pager_v2.bin \ BL33=${RECIPE_SYSROOT}/firmware/uefi.bin \ " diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-tc.inc b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-tc.inc index e17a8f5996..c14629fd19 100644 --- a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-tc.inc +++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a-tc.inc @@ -27,7 +27,7 @@ EXTRA_OEMAKE += "TARGET_PLATFORM=${TFA_TARGET_PLATFORM}" # Set optee as SP. Set spmc manifest and sp layout file to optee DEPENDS += "optee-os" -TFA_SP_LAYOUT_FILE = "${RECIPE_SYSROOT}/lib/firmware/sp_layout.json" +TFA_SP_LAYOUT_FILE = "${RECIPE_SYSROOT}/${nonarch_base_libdir}/firmware/sp_layout.json" TFA_ARM_SPMC_MANIFEST_DTS = "plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts" EXTRA_OEMAKE += "SCP_BL2=${RECIPE_SYSROOT}/firmware/scp_ramfw.bin" diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Enable-Signed-Capsule.patch b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Enable-Signed-Capsule.patch new file mode 100644 index 0000000000..49c336de64 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Enable-Signed-Capsule.patch @@ -0,0 +1,102 @@ +From fa0988fd876400dc1bb451fffc4b167265b40d25 Mon Sep 17 00:00:00 2001 +From: Emekcan Aras +Date: Thu, 14 Sep 2023 12:14:28 +0100 +Subject: [PATCH] Platform: Corstone1000: Enable Signed Capsule + +Enables signed capsule update and adjusts the necessary structs (fmp_payload_header +, image_auth, etc.) to comply with the new capsule generation tool (mkeficapsule). + +Signed-off-by: Emekcan Aras +Upstream-Status: Pending [Not submitted to upstream yet] +--- + .../fw_update_agent/uefi_capsule_parser.c | 25 +++++++++++-------- + .../fw_update_agent/uefi_capsule_parser.h | 2 ++ + 2 files changed, 17 insertions(+), 10 deletions(-) + +diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c +index b72ff1eb91..c706c040ac 100644 +--- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c ++++ b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c +@@ -102,11 +102,9 @@ enum uefi_capsule_error_t uefi_capsule_retrieve_images(void* capsule_ptr, + } + + capsule_header = (efi_capsule_header_t*)ptr; +- ptr += sizeof(efi_capsule_header_t) + sizeof(uint32_t); ++ ptr += sizeof(efi_capsule_header_t); + fmp_capsule_header = (efi_firmware_management_capsule_header_t*)ptr; + +- fmp_payload_header = fmp_capsule_header + sizeof(*fmp_capsule_header); +- + total_size = capsule_header->capsule_image_size; + image_count = fmp_capsule_header->payload_item_count; + images_info->nr_image = image_count; +@@ -119,22 +117,20 @@ enum uefi_capsule_error_t uefi_capsule_retrieve_images(void* capsule_ptr, + } + + for (int i = 0; i < image_count; i++) { +- + image_header = (efi_firmware_management_capsule_image_header_t*)(ptr + + fmp_capsule_header->item_offset_list[i]); + + images_info->size[i] = image_header->update_image_size; +- images_info->version[i] = fmp_payload_header->fw_version; +- FWU_LOG_MSG("%s: image %i version = %u\n\r", __func__, i, +- images_info->version[i]); ++ + #ifdef AUTHENTICATED_CAPSULE + image_auth = (efi_firmware_image_authentication_t*)( + (char*)image_header + + sizeof (efi_firmware_management_capsule_image_header_t) + ); + auth_size = sizeof(uint64_t) /* monotonic_count */ + +- image_auth->auth_info.hdr.dwLength /* WIN_CERTIFICATE + cert_data */ + +- sizeof(struct efi_guid) /* cert_type */; ++ image_auth->auth_info.hdr.dwLength/* WIN_CERTIFICATE + cert_data + cert_type */; ++ ++ fmp_payload_header = (fmp_payload_header_t*)((char*)image_auth + auth_size); + + FWU_LOG_MSG("%s: auth size = %u\n\r", __func__, auth_size); + +@@ -143,16 +139,25 @@ enum uefi_capsule_error_t uefi_capsule_retrieve_images(void* capsule_ptr, + images_info->image[i] = ( + (char*)image_header + + sizeof(efi_firmware_management_capsule_image_header_t) + +- auth_size); ++ auth_size + ++ sizeof(*fmp_payload_header)); + #else + images_info->image[i] = ( + (char*)image_header + + sizeof(efi_firmware_management_capsule_image_header_t) + + sizeof(*fmp_payload_header)); ++ ++ fmp_payload_header = (fmp_payload_header_t*)((char*)image_header + ++ sizeof(efi_firmware_management_capsule_image_header_t)); ++ + #endif + memcpy(&images_info->guid[i], &(image_header->update_image_type_id), + sizeof(struct efi_guid)); + ++ images_info->version[i] = fmp_payload_header->fw_version; ++ FWU_LOG_MSG("%s: image %i version = %d\n\r", __func__, i, ++ images_info->version[i]); ++ + FWU_LOG_MSG("%s: image %d at %p, size=%u\n\r", __func__, i, + images_info->image[i], images_info->size[i]); + +diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h +index a890a709e9..a31cd8a3a0 100644 +--- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h ++++ b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h +@@ -12,6 +12,8 @@ + #include "fip_parser/external/uuid.h" + #include "flash_layout.h" + ++#define AUTHENTICATED_CAPSULE 1 ++ + enum uefi_capsule_error_t { + UEFI_CAPSULE_PARSER_SUCCESS = 0, + UEFI_CAPSULE_PARSER_ERROR = (-1) +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc index a259390a52..601d165236 100644 --- a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc +++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc @@ -33,6 +33,7 @@ SRC_URI:append:corstone1000 = " \ file://0003-Platform-Corstone1000-Calculate-the-new-CRC32-value-.patch \ file://0004-arm-trusted-firmware-m-disable-fatal-warnings.patch \ file://0005-Platform-corstone1000-add-unique-firmware-GUID.patch \ + file://0006-Platform-Corstone1000-Enable-Signed-Capsule.patch \ " # TF-M ships patches for external dependencies that needs to be applied diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0035-dt-Provide-a-way-to-remove-non-compliant-nodes-and-p.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0035-dt-Provide-a-way-to-remove-non-compliant-nodes-and-p.patch new file mode 100644 index 0000000000..25a7aa3069 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0035-dt-Provide-a-way-to-remove-non-compliant-nodes-and-p.patch @@ -0,0 +1,137 @@ +From a37ab0c2578a4627111022d2d1f27f9efa1c2b76 Mon Sep 17 00:00:00 2001 +From: Sughosh Ganu +Date: Thu, 21 Sep 2023 14:13:42 +0100 +Subject: [PATCH 35/37] dt: Provide a way to remove non-compliant nodes and + properties + +Add a function which is registered to spy for a EVT_FT_FIXUP event, +and removes the non upstreamed nodes and properties from the +devicetree before it gets passed to the OS. + +This allows removing entire nodes, or specific properties under nodes +from the devicetree. The required nodes and properties can be +registered for removal through the DT_NON_COMPLIANT_PURGE and +DT_NON_COMPLIANT_PURGE_LIST macros. + +Signed-off-by: Sughosh Ganu +Upstream-Status: Submitted [RFC: https://lore.kernel.org/u-boot/aca7e6fa-2dec-a7c5-e47e-84c5ffa6f9b7@gmx.de/T/#m16d14ee960427cc88066bdcdd76f0a26738bb66d] +--- + include/dt-structs.h | 11 +++++++ + lib/Makefile | 1 + + lib/dt_purge.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 85 insertions(+) + create mode 100644 lib/dt_purge.c + +diff --git a/include/dt-structs.h b/include/dt-structs.h +index fa1622cb1d..f535c60471 100644 +--- a/include/dt-structs.h ++++ b/include/dt-structs.h +@@ -57,3 +57,14 @@ struct phandle_2_arg { + #endif + + #endif ++ ++struct dt_non_compliant_purge { ++ const char *node_path; ++ const char *prop; ++}; ++ ++#define DT_NON_COMPLIANT_PURGE(__name) \ ++ ll_entry_declare(struct dt_non_compliant_purge, __name, dt_purge) ++ ++#define DT_NON_COMPLIANT_PURGE_LIST(__name) \ ++ ll_entry_declare_list(struct dt_non_compliant_purge, __name, dt_purge) +diff --git a/lib/Makefile b/lib/Makefile +index 8d8ccc8bbc..82a906daa0 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -37,6 +37,7 @@ endif + obj-y += crc8.o + obj-y += crc16.o + obj-y += crc16-ccitt.o ++obj-y += dt_purge.o + obj-$(CONFIG_ERRNO_STR) += errno_str.o + obj-$(CONFIG_FIT) += fdtdec_common.o + obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o +diff --git a/lib/dt_purge.c b/lib/dt_purge.c +new file mode 100644 +index 0000000000..f893ba9796 +--- /dev/null ++++ b/lib/dt_purge.c +@@ -0,0 +1,73 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (c) 2023, Linaro Limited ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++/** ++ * dt_non_compliant_purge() - Remove non-upstreamed nodes and properties ++ * from the DT ++ * @ctx: Context for event ++ * @event: Event to process ++ * ++ * Iterate through an array of DT nodes and properties, and remove them ++ * from the device-tree before the DT gets handed over to the kernel. ++ * These are nodes and properties which do not have upstream bindings ++ * and need to be purged before being handed over to the kernel. ++ * ++ * If both the node and property are specified, delete the property. If ++ * only the node is specified, delete the entire node, including it's ++ * subnodes, if any. ++ * ++ * Return: 0 if OK, -ve on error ++ */ ++static int dt_non_compliant_purge(void *ctx, struct event *event) ++{ ++ int nodeoff = 0; ++ int err = 0; ++ void *fdt; ++ const struct event_ft_fixup *fixup = &event->data.ft_fixup; ++ struct dt_non_compliant_purge *purge_entry; ++ struct dt_non_compliant_purge *purge_start = ++ ll_entry_start(struct dt_non_compliant_purge, dt_purge); ++ int nentries = ll_entry_count(struct dt_non_compliant_purge, dt_purge); ++ ++ if (fixup->images) ++ return 0; ++ ++ fdt = fixup->tree.fdt; ++ for (purge_entry = purge_start; purge_entry != purge_start + nentries; ++ purge_entry++) { ++ nodeoff = fdt_path_offset(fdt, purge_entry->node_path); ++ if (nodeoff < 0) { ++ log_debug("Error (%d) getting node offset for %s\n", ++ nodeoff, purge_entry->node_path); ++ continue; ++ } ++ ++ if (purge_entry->prop) { ++ err = fdt_delprop(fdt, nodeoff, purge_entry->prop); ++ if (err < 0 && err != -FDT_ERR_NOTFOUND) { ++ log_debug("Error (%d) deleting %s\n", ++ err, purge_entry->prop); ++ goto out; ++ } ++ } else { ++ err = fdt_del_node(fdt, nodeoff); ++ if (err) { ++ log_debug("Error (%d) trying to delete node %s\n", ++ err, purge_entry->node_path); ++ goto out; ++ } ++ } ++ } ++ ++out: ++ return err; ++} ++EVENT_SPY(EVT_FT_FIXUP, dt_non_compliant_purge); +-- +2.25.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0036-bootefi-Call-the-EVT_FT_FIXUP-event-handler.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0036-bootefi-Call-the-EVT_FT_FIXUP-event-handler.patch new file mode 100644 index 0000000000..2eb273afc6 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0036-bootefi-Call-the-EVT_FT_FIXUP-event-handler.patch @@ -0,0 +1,56 @@ +From 729c0163ae6aed76b3267b95d2989e70ded66716 Mon Sep 17 00:00:00 2001 +From: Sughosh Ganu +Date: Thu, 21 Sep 2023 14:15:13 +0100 +Subject: [PATCH 36/37] bootefi: Call the EVT_FT_FIXUP event handler + +The bootefi command passes the devicetree to the kernel through the +EFI config table. Call the event handlers for fixing the devicetree +before jumping into the kernel. This removes any devicetree nodes +and/or properties that are specific only to U-Boot, and are not to be +passed to the OS. + +Signed-off-by: Sughosh Ganu +Upstream-Status: Submitted [RFC: https://lore.kernel.org/u-boot/aca7e6fa-2dec-a7c5-e47e-84c5ffa6f9b7@gmx.de/T/#m16d14ee960427cc88066bdcdd76f0a26738bb66d] +--- + cmd/bootefi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/cmd/bootefi.c b/cmd/bootefi.c +index 5c0afec154..f9588b66c7 100644 +--- a/cmd/bootefi.c ++++ b/cmd/bootefi.c +@@ -237,6 +237,23 @@ static void *get_config_table(const efi_guid_t *guid) + return NULL; + } + ++/** ++ * event_notify_dt_fixup() - call ft_fixup event ++ * ++ * @fdt: address of the device tree to be passed to the kernel ++ * through the configuration table ++ * Return: None ++ */ ++static void event_notify_dt_fixup(void *fdt) ++{ ++ int ret; ++ struct event_ft_fixup fixup = {0}; ++ ++ fixup.tree.fdt = fdt; ++ ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)); ++ if (ret) ++ printf("Error: %d: FDT Fixup event failed\n", ret); ++} + #endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */ + + /** +@@ -318,6 +335,7 @@ efi_status_t efi_install_fdt(void *fdt) + efi_carve_out_dt_rsv(fdt); + + efi_try_purge_kaslr_seed(fdt); ++ event_notify_dt_fixup(fdt); + + if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) { + ret = efi_tcg2_measure_dtb(fdt); +-- +2.25.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0037-corstone1000-purge-U-Boot-specific-DT-nodes.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0037-corstone1000-purge-U-Boot-specific-DT-nodes.patch new file mode 100644 index 0000000000..2aafadd21f --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0037-corstone1000-purge-U-Boot-specific-DT-nodes.patch @@ -0,0 +1,51 @@ +From 1527eef4dd54a425a5a178f09fa9d3d65aa3e30a Mon Sep 17 00:00:00 2001 +From: Abdellatif El Khlifi +Date: Thu, 21 Sep 2023 15:24:34 +0100 +Subject: [PATCH 37/37] corstone1000: purge U-Boot specific DT nodes + +Remove U-Boot specific DT nodes before passing the DT to Linux + +This is needed to pass SystemReady IR 2.0 dt-schema tests + +Signed-off-by: Abdellatif El Khlifi +Upstream-Status: Pending [RFC: https://lore.kernel.org/u-boot/aca7e6fa-2dec-a7c5-e47e-84c5ffa6f9b7@gmx.de/T/#m16d14ee960427cc88066bdcdd76f0a26738bb66d] +--- + board/armltd/corstone1000/corstone1000.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c +index 53c65506d5..e3c0e5bf50 100644 +--- a/board/armltd/corstone1000/corstone1000.c ++++ b/board/armltd/corstone1000/corstone1000.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -18,6 +19,20 @@ + #include + #include + ++/* remove the DT nodes not needed in Linux */ ++DT_NON_COMPLIANT_PURGE_LIST(foo) = { ++ { .node_path = "/fwu-mdata" }, ++ { .node_path = "/nvmxip-qspi@08000000" }, ++ { .node_path = "/soc/mailbox@1b820000" }, ++ { .node_path = "/soc/mailbox@1b830000" }, ++ { .node_path = "/soc/mhu@1b000000" }, ++ { .node_path = "/soc/mhu@1b010000" }, ++ { .node_path = "/soc/mhu@1b020000" }, ++ { .node_path = "/soc/mhu@1b030000" }, ++ { .node_path = "/soc/client" }, ++ { .node_path = "/soc/extsys@1A010310" }, ++}; ++ + #define CORSTONE1000_KERNEL_PARTS 2 + #define CORSTONE1000_KERNEL_PRIMARY "kernel_primary" + #define CORSTONE1000_KERNEL_SECONDARY "kernel_secondary" +-- +2.25.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0038-corstone1000-add-signature-device-tree-overlay.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0038-corstone1000-add-signature-device-tree-overlay.patch new file mode 100644 index 0000000000..9d8c6a9e5c --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0038-corstone1000-add-signature-device-tree-overlay.patch @@ -0,0 +1,31 @@ +From 88cb6f5a91178903d4e306d8653b941f9727987b Mon Sep 17 00:00:00 2001 +From: Emekcan Aras +Date: Wed, 13 Sep 2023 13:20:15 +0100 +Subject: [PATCH] corstone1000: add signature device tree overlay + +Adds signature device tree overlay. + +Signed-off-by: Emekcan Aras +Upstream-Status: Pending [Not submitted to upstream yet] +--- + arch/arm/dts/corstone1000.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi +index 25a032b6b3..1c3ab2c315 100644 +--- a/arch/arm/dts/corstone1000.dtsi ++++ b/arch/arm/dts/corstone1000.dtsi +@@ -111,6 +111,10 @@ + fwu-mdata-store = <&nvmxip>; + }; + ++ signature { ++ capsule-key = /incbin/("../../../CRT.esl"); ++ }; ++ + soc { + compatible = "simple-bus"; + #address-cells = <1>; +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0039-corstone1000-enable-authenticated-capsule-config.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0039-corstone1000-enable-authenticated-capsule-config.patch new file mode 100644 index 0000000000..761234e6d5 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0039-corstone1000-enable-authenticated-capsule-config.patch @@ -0,0 +1,28 @@ +From 9b884d4f483474b99fcb4850197a1c8dde34147d Mon Sep 17 00:00:00 2001 +From: Emekcan Aras +Date: Wed, 13 Sep 2023 13:52:02 +0100 +Subject: [PATCH] corstone1000: enable authenticated capsule config + +Enables authenticated capsule update config for corstone1000. + +Signed-off-by: Emekcan Aras +Upstream-Status: Pending [Not submitted to upstream yet] +--- + configs/corstone1000_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig +index 5b0b2ac3bf..2de3f5d7b3 100644 +--- a/configs/corstone1000_defconfig ++++ b/configs/corstone1000_defconfig +@@ -70,6 +70,7 @@ CONFIG_FWU_MDATA=y + CONFIG_FWU_MDATA_GPT_BLK=y + CONFIG_SYSRESET=y + CONFIG_EFI_CAPSULE_ON_DISK=y ++CONFIG_EFI_CAPSULE_AUTHENTICATE=y + CONFIG_EFI_IGNORE_OSINDICATIONS=y + CONFIG_FWU_MULTI_BANK_UPDATE=y + # CONFIG_TOOLS_MKEFICAPSULE is not set +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0040-corstone1000-introduce-EFI-authenticated-capsule-upd.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0040-corstone1000-introduce-EFI-authenticated-capsule-upd.patch new file mode 100644 index 0000000000..f47dd8c196 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0040-corstone1000-introduce-EFI-authenticated-capsule-upd.patch @@ -0,0 +1,76 @@ +From b99a39c662b9be5f940b895efa8016f5567e1c1f Mon Sep 17 00:00:00 2001 +From: Emekcan Aras +Date: Wed, 13 Sep 2023 13:55:08 +0100 +Subject: [PATCH] corstone1000: introduce EFI authenticated capsule update + +Introduces EFI authenticated capsule update for corstone1000. Corstone1000 +implements platform-specific capsule update mechanism in u-bootdue to the SoC +design. This patch add authenticated capsule update mechanism to the +platform-specific firmware-update routine. + +Signed-off-by: Emekcan Aras +Upstream-Status: Inappropriate [Redesign of Capsule update interface is required] +--- + lib/efi_loader/efi_capsule.c | 39 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c +index 6a06605ad9..30fb7d1dd5 100644 +--- a/lib/efi_loader/efi_capsule.c ++++ b/lib/efi_loader/efi_capsule.c +@@ -820,6 +820,12 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule( + u64 scatter_gather_list) + { + struct efi_capsule_header *capsule; ++ struct efi_firmware_management_capsule_header *capsule_header; ++ struct efi_firmware_management_capsule_image_header *image; ++ size_t image_binary_size; ++ size_t tmp_capsule_payload_size=0; ++ void *tmp_capsule_payload=NULL; ++ void *image_binary; + unsigned int i; + efi_status_t ret; + +@@ -859,6 +865,39 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule( + goto out; + } + ++ capsule_header = (void *)capsule + capsule->header_size; ++ image = (void *)capsule_header + capsule_header->item_offset_list[0]; ++ if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) && ++ !(image->image_capsule_support & ++ CAPSULE_SUPPORT_AUTHENTICATION)) { ++ /* no signature */ ++ log_err("Corstone1000: Capsule authentication flag check failed. Aborting update\n"); ++ ret = EFI_SECURITY_VIOLATION; ++ goto out; ++ } ++ ++ image_binary = (void *)image + sizeof(*image); ++ image_binary_size = image->update_image_size; ++ if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) && ++ (image->image_capsule_support & ++ CAPSULE_SUPPORT_AUTHENTICATION)){ ++ ret = efi_capsule_authenticate(image_binary, image_binary_size, ++ &tmp_capsule_payload, ++ &tmp_capsule_payload_size); ++ ++ if (ret == EFI_SECURITY_VIOLATION) { ++ log_err("Corstone1000: Capsule authentication check failed. Aborting update\n"); ++ goto out; ++ } else if (ret != EFI_SUCCESS) { ++ goto out; ++ } ++ ++ log_debug("Corstone1000: Capsule authentication successful\n"); ++ } else { ++ log_debug("Corstone1000: Capsule authentication disabled. "); ++ log_debug("Corstone1000: Updating capsule without authenticating.\n"); ++ } ++ + /* copy the data to the contiguous buffer */ + efi_memcpy_runtime(corstone1000_capsule_buf, capsule, capsule->capsule_image_size); + +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0001-armv8-Add-ARMv8-MPU-configuration-logic.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0001-armv8-Add-ARMv8-MPU-configuration-logic.patch deleted file mode 100644 index 45db74e133..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0001-armv8-Add-ARMv8-MPU-configuration-logic.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 401a88bf6019941d4095476de76af5893686d6f6 Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Wed, 26 May 2021 17:41:10 +0100 -Subject: [PATCH] armv8: Add ARMv8 MPU configuration logic - -Detect whether an MMU is present at the current exception level. If -not, initialize the MPU instead of the MMU during init, and clear the -MPU regions before transition to Linux. - -The MSA in use at EL1&0 may be configurable but can only by determined -by inspecting VTCR_EL2 at EL2, so assume that there is an MMU for -backwards compatibility. - -Provide a default (blank) MPU memory map, which can be overridden by -board configurations. - -Issue-Id: SCM-2443 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Change-Id: I0ee3879f9d7f03fe940664b3551c68eeaa458d17 - ---- - arch/arm/cpu/armv8/cache_v8.c | 101 ++++++++++++++++++++++++++++++- - arch/arm/include/asm/armv8/mpu.h | 59 ++++++++++++++++++ - arch/arm/include/asm/system.h | 19 ++++++ - 3 files changed, 176 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/include/asm/armv8/mpu.h - -diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c -index 2a226fd063..8611a35eb3 100644 ---- a/arch/arm/cpu/armv8/cache_v8.c -+++ b/arch/arm/cpu/armv8/cache_v8.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - DECLARE_GLOBAL_DATA_PTR; - -@@ -385,6 +386,91 @@ __weak u64 get_page_table_size(void) - return size; - } - -+static void mpu_clear_regions(void) -+{ -+ int i; -+ -+ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) { -+ setup_el2_mpu_region(i, 0, 0); -+ } -+} -+ -+static struct mpu_region default_mpu_mem_map[] = {{0,}}; -+__weak struct mpu_region *mpu_mem_map = default_mpu_mem_map; -+ -+static void mpu_setup(void) -+{ -+ int i; -+ -+ if (current_el() != 2) { -+ panic("MPU configuration is only supported at EL2"); -+ } -+ -+ set_sctlr(get_sctlr() & ~(CR_M | CR_WXN)); -+ -+ asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES); -+ -+ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) { -+ setup_el2_mpu_region(i, -+ PRBAR_ADDRESS(mpu_mem_map[i].start) -+ | PRBAR_OUTER_SH | PRBAR_AP_RW_ANY, -+ PRLAR_ADDRESS(mpu_mem_map[i].end) -+ | mpu_mem_map[i].attrs | PRLAR_EN_BIT -+ ); -+ } -+ -+ set_sctlr(get_sctlr() | CR_M); -+} -+ -+static bool el_has_mmu(void) -+{ -+ if (current_el() < 2) { -+ // We have no way of knowing, so assuming we have an MMU -+ return true; -+ } -+ -+ uint64_t id_aa64mmfr0; -+ asm volatile("mrs %0, id_aa64mmfr0_el1" -+ : "=r" (id_aa64mmfr0) : : "cc"); -+ uint64_t msa = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_MASK; -+ uint64_t msa_frac = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_FRAC_MASK; -+ -+ switch (msa) { -+ case ID_AA64MMFR0_EL1_MSA_VMSA: -+ /* -+ * VMSA supported in all translation regimes. -+ * No support for PMSA. -+ */ -+ return true; -+ case ID_AA64MMFR0_EL1_MSA_USE_FRAC: -+ /* See MSA_frac for the supported MSAs. */ -+ switch (msa_frac) { -+ case ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA: -+ /* -+ * PMSA not supported in any translation -+ * regime. -+ */ -+ return true; -+ case ID_AA64MMFR0_EL1_MSA_FRAC_VMSA: -+ /* -+ * PMSA supported in all translation -+ * regimes. No support for VMSA. -+ */ -+ case ID_AA64MMFR0_EL1_MSA_FRAC_PMSA: -+ /* -+ * PMSA supported in all translation -+ * regimes. -+ */ -+ return false; -+ default: -+ panic("Unsupported id_aa64mmfr0_el1 " \ -+ "MSA_frac value"); -+ } -+ default: -+ panic("Unsupported id_aa64mmfr0_el1 MSA value"); -+ } -+} -+ - void setup_pgtables(void) - { - int i; -@@ -499,8 +585,13 @@ void dcache_enable(void) - /* The data cache is not active unless the mmu is enabled */ - if (!(get_sctlr() & CR_M)) { - invalidate_dcache_all(); -- __asm_invalidate_tlb_all(); -- mmu_setup(); -+ -+ if (el_has_mmu()) { -+ __asm_invalidate_tlb_all(); -+ mmu_setup(); -+ } else { -+ mpu_setup(); -+ } - } - - /* Set up page tables only once (it is done also by mmu_setup()) */ -@@ -523,7 +614,11 @@ void dcache_disable(void) - set_sctlr(sctlr & ~(CR_C|CR_M)); - - flush_dcache_all(); -- __asm_invalidate_tlb_all(); -+ -+ if (el_has_mmu()) -+ __asm_invalidate_tlb_all(); -+ else -+ mpu_clear_regions(); - } - - int dcache_status(void) -diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h -new file mode 100644 -index 0000000000..8de627cafd ---- /dev/null -+++ b/arch/arm/include/asm/armv8/mpu.h -@@ -0,0 +1,59 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0+ -+ * -+ * (C) Copyright 2021 Arm Limited -+ */ -+ -+#ifndef _ASM_ARMV8_MPU_H_ -+#define _ASM_ARMV8_MPU_H_ -+ -+#include -+#include -+ -+#define PRSELR_EL2 S3_4_c6_c2_1 -+#define PRBAR_EL2 S3_4_c6_c8_0 -+#define PRLAR_EL2 S3_4_c6_c8_1 -+#define MPUIR_EL2 S3_4_c0_c0_4 -+ -+#define PRBAR_ADDRESS(addr) ((addr) & ~(0x3fULL)) -+ -+/* Access permissions */ -+#define PRBAR_AP(val) (((val) & 0x3) << 2) -+#define PRBAR_AP_RW_HYP PRBAR_AP(0x0) -+#define PRBAR_AP_RW_ANY PRBAR_AP(0x1) -+#define PRBAR_AP_RO_HYP PRBAR_AP(0x2) -+#define PRBAR_AP_RO_ANY PRBAR_AP(0x3) -+ -+/* Shareability */ -+#define PRBAR_SH(val) (((val) & 0x3) << 4) -+#define PRBAR_NON_SH PRBAR_SH(0x0) -+#define PRBAR_OUTER_SH PRBAR_SH(0x2) -+#define PRBAR_INNER_SH PRBAR_SH(0x3) -+ -+/* Memory attribute (MAIR idx) */ -+#define PRLAR_ATTRIDX(val) (((val) & 0x7) << 1) -+#define PRLAR_EN_BIT (0x1) -+#define PRLAR_ADDRESS(addr) ((addr) & ~(0x3fULL)) -+ -+#ifndef __ASSEMBLY__ -+ -+static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t limit) -+{ -+ asm volatile("msr " __stringify(PRSELR_EL2) ", %0" : : "r" (region)); -+ asm volatile("msr " __stringify(PRBAR_EL2) ", %0" : : "r" (base)); -+ asm volatile("msr " __stringify(PRLAR_EL2) ", %0" : : "r" (limit)); -+ -+ asm volatile("isb"); -+} -+ -+#endif -+ -+struct mpu_region { -+ u64 start; -+ u64 end; -+ u64 attrs; -+}; -+ -+extern struct mpu_region *mpu_mem_map; -+ -+#endif /* _ASM_ARMV8_MPU_H_ */ -diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h -index 87d1c77e8b..4510db98a2 100644 ---- a/arch/arm/include/asm/system.h -+++ b/arch/arm/include/asm/system.h -@@ -95,6 +95,25 @@ - auth algorithm */ - #define ID_AA64ISAR1_EL1_APA (0xF << 4) /* QARMA address auth algorithm */ - -+/* -+ * ID_AA64MMFR0_EL1 bits definitions -+ */ -+#define ID_AA64MMFR0_EL1_MSA_FRAC_MASK (0xFUL << 52) /* Memory system -+ architecture -+ frac */ -+#define ID_AA64MMFR0_EL1_MSA_FRAC_VMSA (0x2UL << 52) /* EL1&0 supports -+ VMSA */ -+#define ID_AA64MMFR0_EL1_MSA_FRAC_PMSA (0x1UL << 52) /* EL1&0 only -+ supports PMSA*/ -+#define ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA (0x0UL << 52) /* No PMSA -+ support */ -+#define ID_AA64MMFR0_EL1_MSA_MASK (0xFUL << 48) /* Memory system -+ architecture */ -+#define ID_AA64MMFR0_EL1_MSA_USE_FRAC (0xFUL << 48) /* Use MSA_FRAC */ -+#define ID_AA64MMFR0_EL1_MSA_VMSA (0x0UL << 48) /* Memory system -+ architecture -+ is VMSA */ -+ - /* - * ID_AA64PFR0_EL1 bits definitions - */ diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch deleted file mode 100644 index 103e48479c..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 5b42322cb57692dbea7d2c39fd8769b6f0f6b7af Mon Sep 17 00:00:00 2001 -From: Qi Feng -Date: Tue, 26 Jul 2022 18:13:23 +0800 -Subject: [PATCH] vexpress64: add MPU memory map for the BASER_FVP - -The previous patch added support for initializing an Armv8 MPU. There is only an -MPU at S-EL2 on the BASER_FVP, so add a platform-specific MPU memory map. - -See https://developer.arm.com/documentation/100964/1117/Base-Platform/Base---memory/BaseR-Platform-memory-map - -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Signed-off-by: Qi Feng - ---- - board/armltd/vexpress64/vexpress64.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c -index af326dc6f4..2310d18eb7 100644 ---- a/board/armltd/vexpress64/vexpress64.c -+++ b/board/armltd/vexpress64/vexpress64.c -@@ -19,6 +19,7 @@ - #include - #include "pcie.h" - #include -+#include - #ifdef CONFIG_VIRTIO_NET - #include - #include -@@ -37,6 +38,27 @@ U_BOOT_DRVINFO(vexpress_serials) = { - .plat = &serial_plat, - }; - -+static struct mpu_region vexpress64_aemv8r_mem_map[] = { -+ { -+ .start = 0x0UL, -+ .end = 0x7fffffffUL, -+ .attrs = PRLAR_ATTRIDX(MT_NORMAL) -+ }, { -+ .start = 0x80000000UL, -+ .end = 0xffffffffUL, -+ .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE) -+ }, { -+ .start = 0x100000000UL, -+ .end = 0xffffffffffUL, -+ .attrs = PRLAR_ATTRIDX(MT_NORMAL) -+ }, { -+ /* List terminator */ -+ 0, -+ } -+}; -+ -+struct mpu_region *mpu_mem_map = vexpress64_aemv8r_mem_map; -+ - static struct mm_region vexpress64_mem_map[] = { - { - .virt = V2M_PA_BASE, diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch deleted file mode 100644 index 5953abc652..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch +++ /dev/null @@ -1,104 +0,0 @@ -From ffb0f72a67926c3053308cf03420bc0c36675d42 Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Fri, 10 Dec 2021 11:41:19 +0000 -Subject: [PATCH] armv8: Allow disabling exception vectors on non-SPL builds - -On the BASER_FVP, U-Boot shares EL2 with another bootloader, so we do -not wish to overide the exception vector, but we are also not using an -SPL build. - -Therefore, add ARMV8_EXCEPTION_VECTORS, which disables exception vectors -in a similar way to ARMV8_SPL_EXCEPTION_VECTORS. - -Rename ARMV8_SPL_EXCEPTION_VECTORS -> SPL_ARMV8_EXCEPTION_VECTORS so -that both config flags be be targeted using CONFIG_IS_ENABLED. - -Issue-Id: SCM-3728 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Change-Id: I0cf0fc6d7ef4d45791411cf1f67c65e198cc8b2b - ---- - arch/arm/cpu/armv8/Kconfig | 10 ++++++++-- - arch/arm/cpu/armv8/Makefile | 6 ++---- - arch/arm/cpu/armv8/start.S | 4 ++-- - configs/vexpress_aemv8r_defconfig | 1 + - 4 files changed, 13 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig -index 1305238c9d..dec4be0e30 100644 ---- a/arch/arm/cpu/armv8/Kconfig -+++ b/arch/arm/cpu/armv8/Kconfig -@@ -1,8 +1,8 @@ - if ARM64 - --config ARMV8_SPL_EXCEPTION_VECTORS -+config ARMV8_EXCEPTION_VECTORS - bool "Install crash dump exception vectors" -- depends on SPL -+ default y - help - The default exception vector table is only used for the crash - dump, but still takes quite a lot of space in the image size. -@@ -10,6 +10,12 @@ config ARMV8_SPL_EXCEPTION_VECTORS - Say N here if you are running out of code space in the image - and want to save some space at the cost of less debugging info. - -+config SPL_ARMV8_EXCEPTION_VECTORS -+ bool "Install crash dump exception vectors in the SPL" -+ depends on SPL -+ help -+ Same as ARMV8_EXCEPTION_VECTORS, but for SPL builds -+ - config ARMV8_MULTIENTRY - bool "Enable multiple CPUs to enter into U-Boot" - -diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile -index 2e4bf9e038..001a31cae7 100644 ---- a/arch/arm/cpu/armv8/Makefile -+++ b/arch/arm/cpu/armv8/Makefile -@@ -13,10 +13,8 @@ ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF - obj-y += cache_v8.o - obj-y += cache.o - endif --ifdef CONFIG_SPL_BUILD --obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o --else --obj-y += exceptions.o -+obj-$(CONFIG_$(SPL_)ARMV8_EXCEPTION_VECTORS) += exceptions.o -+ifndef CONFIG_SPL_BUILD - obj-y += exception_level.o - endif - obj-y += tlb.o -diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S -index f3ea858577..7fad901336 100644 ---- a/arch/arm/cpu/armv8/start.S -+++ b/arch/arm/cpu/armv8/start.S -@@ -104,7 +104,7 @@ pie_skip_reloc: - pie_fixup_done: - #endif - --#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD) -+#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS) - .macro set_vbar, regname, reg - msr \regname, \reg - .endm -@@ -354,7 +354,7 @@ ENDPROC(smp_kick_all_cpus) - /*-----------------------------------------------------------------------*/ - - ENTRY(c_runtime_cpu_setup) --#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD) -+#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS) - /* Relocate vBAR */ - adr x0, vectors - switch_el x1, 3f, 2f, 1f -diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig -index 495eb1dee3..683d983c36 100644 ---- a/configs/vexpress_aemv8r_defconfig -+++ b/configs/vexpress_aemv8r_defconfig -@@ -16,3 +16,4 @@ CONFIG_SYS_CBSIZE=512 - CONFIG_SYS_PBSIZE=541 - # CONFIG_MMC is not set - CONFIG_VIRTIO_MMIO=y -+CONFIG_ARMV8_EXCEPTION_VECTORS=n diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch deleted file mode 100644 index 157a15d7df..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 14e204ffca5870d6bfd238627937a2028c88589d Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Wed, 14 Jul 2021 12:44:27 +0100 -Subject: [PATCH] armv8: ARMV8_SWITCH_TO_EL1 improvements - -Convert CONFIG_ARMV8_SWITCH_TO_EL1 to a Kconfig variable. - -Add support for switching to EL1 to bootefi. - -Add the environment variable armv8_switch_to_el1 to allow configuring -whether to switch to EL1 at runtime. This overrides the compile-time -option. - -Issue-Id: SCM-3728 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Change-Id: If98478148d6d8d1f732acac5439276700614815f - ---- - arch/arm/cpu/armv8/exception_level.c | 21 ++++++++++++++-- - arch/arm/lib/bootm.c | 36 ++++++++++++++++------------ - configs/vexpress_aemv8r_defconfig | 1 + - 3 files changed, 41 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c -index b11936548f..4aad1550f4 100644 ---- a/arch/arm/cpu/armv8/exception_level.c -+++ b/arch/arm/cpu/armv8/exception_level.c -@@ -40,19 +40,36 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp) - * trusted firmware being one embodiment). The operating system shall be - * started at exception level EL2. So here we check the exception level - * and switch it if necessary. -+ * -+ * If armv8_switch_to_el1 (config or env var) is enabled, also switch to EL1 -+ * before booting the operating system. - */ - void switch_to_non_secure_mode(void) - { - struct jmp_buf_data non_secure_jmp; - - /* On AArch64 we need to make sure we call our payload in < EL3 */ -- if (current_el() == 3) { -+ -+ int switch_to_el1 = env_get_yesno("armv8_switch_to_el1"); -+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 -+ if (switch_to_el1 == -1) { -+ switch_to_el1 = 1; -+ } -+#endif -+ -+ if (current_el() > 2) { - if (setjmp(&non_secure_jmp)) - return; - dcache_disable(); /* flush cache before switch to EL2 */ -- - /* Move into EL2 and keep running there */ - armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0, - (uintptr_t)entry_non_secure, ES_TO_AARCH64); -+ } else if (switch_to_el1 == 1 && current_el() > 1) { -+ if (setjmp(&non_secure_jmp)) -+ return; -+ dcache_disable(); /* flush cache before switch to EL1 */ -+ /* Move into EL1 and keep running there */ -+ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0, -+ (uintptr_t)entry_non_secure, ES_TO_AARCH64); - } - } -diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c -index e414ef8267..9a86c17d2a 100644 ---- a/arch/arm/lib/bootm.c -+++ b/arch/arm/lib/bootm.c -@@ -270,7 +270,6 @@ __weak void update_os_arch_secondary_cores(uint8_t os_arch) - { - } - --#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 - static void switch_to_el1(void) - { - if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) && -@@ -285,7 +284,6 @@ static void switch_to_el1(void) - ES_TO_AARCH64); - } - #endif --#endif - - /* Subcommand: GO */ - static void boot_jump_linux(struct bootm_headers *images, int flag) -@@ -312,21 +310,29 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) - - update_os_arch_secondary_cores(images->os.arch); - -+ int armv8_switch_to_el1 = env_get_yesno("armv8_switch_to_el1"); - #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 -- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0, -- (u64)switch_to_el1, ES_TO_AARCH64); --#else -- if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) && -- (images->os.arch == IH_ARCH_ARM)) -- armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number, -- (u64)images->ft_addr, 0, -- (u64)images->ep, -- ES_TO_AARCH32); -- else -- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0, -- images->ep, -- ES_TO_AARCH64); -+ if (armv8_switch_to_el1 == -1) { -+ armv8_switch_to_el1 = 1; -+ } - #endif -+ if (armv8_switch_to_el1 == 1) { -+ armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0, -+ (u64)switch_to_el1, ES_TO_AARCH64); -+ } else { -+ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) && -+ (images->os.arch == IH_ARCH_ARM)) -+ armv8_switch_to_el2(0, -+ (u64)gd->bd->bi_arch_number, -+ (u64)images->ft_addr, 0, -+ (u64)images->ep, -+ ES_TO_AARCH32); -+ else -+ armv8_switch_to_el2((u64)images->ft_addr, -+ 0, 0, 0, -+ images->ep, -+ ES_TO_AARCH64); -+ } - } - #else - unsigned long machid = gd->bd->bi_arch_number; -diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig -index 683d983c36..6044f82b00 100644 ---- a/configs/vexpress_aemv8r_defconfig -+++ b/configs/vexpress_aemv8r_defconfig -@@ -17,3 +17,4 @@ CONFIG_SYS_PBSIZE=541 - # CONFIG_MMC is not set - CONFIG_VIRTIO_MMIO=y - CONFIG_ARMV8_EXCEPTION_VECTORS=n -+CONFIG_ARMV8_SWITCH_TO_EL1=y diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0005-armv8-Make-disabling-HVC-configurable-when-switching.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0005-armv8-Make-disabling-HVC-configurable-when-switching.patch deleted file mode 100644 index 82926cc36e..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0005-armv8-Make-disabling-HVC-configurable-when-switching.patch +++ /dev/null @@ -1,80 +0,0 @@ -From e3d24bc1fd0b09915b5181de1282f7008bbf776f Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Fri, 10 Dec 2021 16:37:26 +0000 -Subject: [PATCH] armv8: Make disabling HVC configurable when switching to EL1 - -On the BASER_FVP there is no EL3, so HVC is used to provide PSCI -services. Therefore we cannot disable hypercalls. - -Create CONFIG_ARMV8_DISABLE_HVC (dependent on CONFIG_ARMV8_TO_EL1) to -control whether to disable HVC exceptions in HCR_EL2->HCD - -Issue-Id: SCM-3728 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Change-Id: I463d82f1db8a3cafcab40a9c0c208753569cc300 - ---- - arch/arm/cpu/armv8/Kconfig | 9 +++++++++ - arch/arm/include/asm/macro.h | 10 ++++++++-- - configs/vexpress_aemv8r_defconfig | 1 + - 3 files changed, 18 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig -index dec4be0e30..95c03487a2 100644 ---- a/arch/arm/cpu/armv8/Kconfig -+++ b/arch/arm/cpu/armv8/Kconfig -@@ -208,4 +208,13 @@ config ARMV8_CE_SHA256 - - endif - -+config ARMV8_DISABLE_HVC -+ bool "Disable HVC calls before switching to EL1" -+ depends on ARMV8_SWITCH_TO_EL1 -+ default y -+ help -+ If switching to EL1 before loading the operating system, disable taking -+ hypercalls back to EL2. May be disabled if, for example, PSCI services are -+ running at EL2. -+ - endif -diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h -index 1a1edc9870..7167739210 100644 ---- a/arch/arm/include/asm/macro.h -+++ b/arch/arm/include/asm/macro.h -@@ -296,9 +296,12 @@ lr .req x30 - ldr \tmp2, =(ID_AA64ISAR1_EL1_GPI | ID_AA64ISAR1_EL1_GPA | \ - ID_AA64ISAR1_EL1_API | ID_AA64ISAR1_EL1_APA) - tst \tmp, \tmp2 -- mov \tmp2, #(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS) -+ mov \tmp2, #(HCR_EL2_RW_AARCH64) - orr \tmp, \tmp2, #(HCR_EL2_APK | HCR_EL2_API) - csel \tmp, \tmp2, \tmp, eq -+#ifdef CONFIG_ARMV8_DISABLE_HVC -+ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS) -+#endif - msr hcr_el2, \tmp - - /* Return to the EL1_SP1 mode from EL2 */ -@@ -311,7 +314,10 @@ lr .req x30 - - 1: - /* Initialize HCR_EL2 */ -- ldr \tmp, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS) -+ ldr \tmp, =(HCR_EL2_RW_AARCH32) -+#ifdef CONFIG_ARMV8_DISABLE_HVC -+ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS) -+#endif - msr hcr_el2, \tmp - - /* Return to AArch32 Supervisor mode from EL2 */ -diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig -index 6044f82b00..6226f6b2c1 100644 ---- a/configs/vexpress_aemv8r_defconfig -+++ b/configs/vexpress_aemv8r_defconfig -@@ -18,3 +18,4 @@ CONFIG_SYS_PBSIZE=541 - CONFIG_VIRTIO_MMIO=y - CONFIG_ARMV8_EXCEPTION_VECTORS=n - CONFIG_ARMV8_SWITCH_TO_EL1=y -+CONFIG_ARMV8_DISABLE_HVC=n diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch deleted file mode 100644 index eb2273e565..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 571f44d5292cfead6f68bf4c6c9519872337bfd0 Mon Sep 17 00:00:00 2001 -From: Qi Feng -Date: Thu, 28 Jul 2022 17:47:18 +0800 -Subject: [PATCH] vexpress64: Do not set COUNTER_FREQUENCY - -VExpress boards normally run as a second-stage bootloader so should not -need to modify CNTFRQ_EL0. On the BASER_FVP, U-Boot can modify it if -running at EL2, but shouldn't because it might be different from the -value being used by the first-stage bootloader (which might be -providing PSCI services). - -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Signed-off-by: Qi Feng - ---- - configs/vexpress_aemv8r_defconfig | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig -index 6226f6b2c1..b902a6a7d9 100644 ---- a/configs/vexpress_aemv8r_defconfig -+++ b/configs/vexpress_aemv8r_defconfig -@@ -1,5 +1,4 @@ - CONFIG_ARM=y --CONFIG_COUNTER_FREQUENCY=24000000 - CONFIG_ARCH_VEXPRESS64=y - CONFIG_NR_DRAM_BANKS=2 - CONFIG_DEFAULT_DEVICE_TREE="arm_fvp" diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch deleted file mode 100644 index 6f5bfa38c4..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch +++ /dev/null @@ -1,25 +0,0 @@ -From df01346bb63c821cf8e73202e2894ceda9cb692b Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Tue, 22 Feb 2022 15:32:51 +0000 -Subject: [PATCH] vexpress64: Enable LIBFDT_OVERLAY in the vexpress_aemv8r - defconfig - -Issue-Id: SCM-3874 -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Signed-off-by: Peter Hoyes -Change-Id: Ide0532cf2de89f1bca9c8d4bd2ed0c1a1c57599f - ---- - configs/vexpress_aemv8r_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig -index b902a6a7d9..a58a9db385 100644 ---- a/configs/vexpress_aemv8r_defconfig -+++ b/configs/vexpress_aemv8r_defconfig -@@ -18,3 +18,4 @@ CONFIG_VIRTIO_MMIO=y - CONFIG_ARMV8_EXCEPTION_VECTORS=n - CONFIG_ARMV8_SWITCH_TO_EL1=y - CONFIG_ARMV8_DISABLE_HVC=n -+CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch deleted file mode 100644 index 61bdf928f4..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 665ab8253a0e3e17db54a1682bbee0f5659939a2 Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Wed, 18 May 2022 15:24:19 +0100 -Subject: [PATCH] armv8: Allow PRBAR MPU attributes to be configured - -In a previous patch, support was added to initialize an S-EL2 MPU on -armv8r64 machines. This implementation allowed the PRLAR attribute -index to be configured, but not the shareability and access permission -attributes in PRBAR. These attributes were hard-coded as "outer -shareable" and "read/write at EL1 and EL0". - -Add separate prlar_attrs and prbar_attrs to the MPU region struct so -that these attributes can be configured on a per-region basis. - -For the BASER_FVP, ensure the MPU memory attributes match those in the -existing vexpress64 board MMU configuration ("non shareable" for device -memory and "inner shareable" for normal memory). - -Issue-Id: SCM-4641 -Signed-off-by: Peter Hoyes -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Change-Id: I6b72aead91ad12412262aa32c61a53e12eab3984 - ---- - arch/arm/cpu/armv8/cache_v8.c | 12 ++++++++---- - arch/arm/include/asm/armv8/mpu.h | 3 ++- - board/armltd/vexpress64/vexpress64.c | 9 ++++++--- - 3 files changed, 16 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c -index 8611a35eb3..f7de952187 100644 ---- a/arch/arm/cpu/armv8/cache_v8.c -+++ b/arch/arm/cpu/armv8/cache_v8.c -@@ -390,7 +390,9 @@ static void mpu_clear_regions(void) - { - int i; - -- for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) { -+ for (i = 0; mpu_mem_map[i].end || -+ mpu_mem_map[i].prbar_attrs || -+ mpu_mem_map[i].prlar_attrs; i++) { - setup_el2_mpu_region(i, 0, 0); - } - } -@@ -410,12 +412,14 @@ static void mpu_setup(void) - - asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES); - -- for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) { -+ for (i = 0; mpu_mem_map[i].end || -+ mpu_mem_map[i].prbar_attrs || -+ mpu_mem_map[i].prlar_attrs; i++) { - setup_el2_mpu_region(i, - PRBAR_ADDRESS(mpu_mem_map[i].start) -- | PRBAR_OUTER_SH | PRBAR_AP_RW_ANY, -+ | mpu_mem_map[i].prbar_attrs, - PRLAR_ADDRESS(mpu_mem_map[i].end) -- | mpu_mem_map[i].attrs | PRLAR_EN_BIT -+ | mpu_mem_map[i].prlar_attrs | PRLAR_EN_BIT - ); - } - -diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h -index 8de627cafd..dd4c689ea6 100644 ---- a/arch/arm/include/asm/armv8/mpu.h -+++ b/arch/arm/include/asm/armv8/mpu.h -@@ -51,7 +51,8 @@ static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t - struct mpu_region { - u64 start; - u64 end; -- u64 attrs; -+ u64 prbar_attrs; -+ u64 prlar_attrs; - }; - - extern struct mpu_region *mpu_mem_map; -diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c -index 2310d18eb7..531fa4d618 100644 ---- a/board/armltd/vexpress64/vexpress64.c -+++ b/board/armltd/vexpress64/vexpress64.c -@@ -42,15 +42,18 @@ static struct mpu_region vexpress64_aemv8r_mem_map[] = { - { - .start = 0x0UL, - .end = 0x7fffffffUL, -- .attrs = PRLAR_ATTRIDX(MT_NORMAL) -+ .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY, -+ .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL) - }, { - .start = 0x80000000UL, - .end = 0xffffffffUL, -- .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE) -+ .prbar_attrs = PRBAR_OUTER_SH | PRBAR_AP_RW_ANY, -+ .prlar_attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE) - }, { - .start = 0x100000000UL, - .end = 0xffffffffffUL, -- .attrs = PRLAR_ATTRIDX(MT_NORMAL) -+ .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY, -+ .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL) - }, { - /* List terminator */ - 0, diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Enable-icache-when-switching-exception-levels-.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Enable-icache-when-switching-exception-levels-.patch deleted file mode 100644 index a4bc746e30..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Enable-icache-when-switching-exception-levels-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c7301588a3aec9ebf36749da601d0d6e3d807bfc Mon Sep 17 00:00:00 2001 -From: Peter Hoyes -Date: Thu, 19 May 2022 09:02:32 +0100 -Subject: [PATCH] armv8: Enable icache when switching exception levels in - bootefi - -bootefi calls the function switch_to_non_secure_mode before calling the -UEFI payload to handle the case where U-Boot is running at EL3. - -For AArch64, the UEFI specification states that: - The core will be configured as follows: - * MMU enabled - * Instruction and data caches enabled - -These requirements should be followed when switching exception levels -for EFI applications. - -This function already disables and re-enables the data cache prior to -switching exception levels, but omits the instruction cache, meaning -the function returns with the instruction cache disabled at the new -exception level. Fix this by calling icache_disable prior to switching -exception levels and icache_enable afterwards. - -Issue-Id: SCM-4641 -Signed-off-by: Peter Hoyes -Upstream-Status: Inappropriate [other] - Implementation pending further discussion -Change-Id: I678cd5ba39b56e124ab7854608289cd14651ce65 - ---- - arch/arm/cpu/armv8/exception_level.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c -index 4aad1550f4..0a3e5428e7 100644 ---- a/arch/arm/cpu/armv8/exception_level.c -+++ b/arch/arm/cpu/armv8/exception_level.c -@@ -27,6 +27,7 @@ - static void entry_non_secure(struct jmp_buf_data *non_secure_jmp) - { - dcache_enable(); -+ icache_enable(); - debug("Reached non-secure mode\n"); - - /* Restore stack and registers saved in switch_to_non_secure_mode() */ -@@ -61,6 +62,7 @@ void switch_to_non_secure_mode(void) - if (setjmp(&non_secure_jmp)) - return; - dcache_disable(); /* flush cache before switch to EL2 */ -+ icache_disable(); - /* Move into EL2 and keep running there */ - armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0, - (uintptr_t)entry_non_secure, ES_TO_AARCH64); -@@ -68,6 +70,7 @@ void switch_to_non_secure_mode(void) - if (setjmp(&non_secure_jmp)) - return; - dcache_disable(); /* flush cache before switch to EL1 */ -+ icache_disable(); - /* Move into EL1 and keep running there */ - armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0, - (uintptr_t)entry_non_secure, ES_TO_AARCH64); diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend index d1dcd74557..c2916a5559 100644 --- a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend @@ -3,7 +3,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" # # Corstone1000 64-bit machines # -DEPENDS:append:corstone1000 = " gnutls-native" +DEPENDS:append:corstone1000 = " gnutls-native openssl-native efitools-native" CORSTONE1000_DEVICE_TREE:corstone1000-mps3 = "corstone1000-mps3" CORSTONE1000_DEVICE_TREE:corstone1000-fvp = "corstone1000-fvp" EXTRA_OEMAKE:append:corstone1000 = ' DEVICE_TREE=${CORSTONE1000_DEVICE_TREE}' @@ -45,31 +45,30 @@ SRC_URI:append:corstone1000 = " \ file://0032-Enable-EFI-set-get-time-services.patch \ file://0033-corstone1000-detect-inflated-kernel-size.patch \ file://0034-corstone1000-ESRT-add-unique-firmware-GUID.patch \ + file://0035-dt-Provide-a-way-to-remove-non-compliant-nodes-and-p.patch \ + file://0036-bootefi-Call-the-EVT_FT_FIXUP-event-handler.patch \ + file://0037-corstone1000-purge-U-Boot-specific-DT-nodes.patch \ + file://0038-corstone1000-add-signature-device-tree-overlay.patch \ + file://0039-corstone1000-enable-authenticated-capsule-config.patch \ + file://0040-corstone1000-introduce-EFI-authenticated-capsule-upd.patch \ " +do_configure:append:corstone1000(){ + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ -keyout ${B}/CRT.key -out ${B}/CRT.crt -nodes -days 365 + cert-to-efi-sig-list ${B}/CRT.crt ${B}/corstone1000_defconfig/CRT.esl +} + +do_install:append:corstone1000() { + install -D -p -m 0644 ${B}/CRT.crt ${DEPLOY_DIR_IMAGE}/corstone1000_capsule_cert.crt + install -D -p -m 0644 ${B}/CRT.key ${DEPLOY_DIR_IMAGE}/corstone1000_capsule_key.key +} + # # FVP BASE # SRC_URI:append:fvp-base = " file://bootargs.cfg \ file://0001-Revert-vexpress64-pick-DRAM-size-from-DT.patch \ " - -# -# FVP BASER -# -SRC_URI:append:fvp-baser-aemv8r64 = " \ - file://0001-armv8-Add-ARMv8-MPU-configuration-logic.patch \ - file://0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch \ - file://0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch \ - file://0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch \ - file://0005-armv8-Make-disabling-HVC-configurable-when-switching.patch \ - file://0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch \ - file://0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch \ - file://0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch \ - file://0009-armv8-Enable-icache-when-switching-exception-levels-.patch \ - " - - # # Juno Machines # diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/uefi/edk2-firmware_202305.bb b/meta-arm/meta-arm-bsp/recipes-bsp/uefi/edk2-firmware_202305.bb new file mode 100644 index 0000000000..23325503a1 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/uefi/edk2-firmware_202305.bb @@ -0,0 +1,7 @@ +SRCREV_edk2 ?= "ba91d0292e593df8528b66f99c1b0b14fadc8e16" +SRCREV_edk2-platforms ?= "be2af02a3fb202756ed9855173e0d0ed878ab6be" + +# FIXME - clang is having issues with antlr +TOOLCHAIN:aarch64 = "gcc" + +require recipes-bsp/uefi/edk2-firmware.inc diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-preempt-rt.scc b/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-preempt-rt.scc deleted file mode 100644 index e8fea0b822..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-preempt-rt.scc +++ /dev/null @@ -1,6 +0,0 @@ -define KMACHINE fvp-baser-aemv8r64 -define KTYPE preempt-rt -define KARCH arm64 - -include ktypes/preempt-rt/preempt-rt.scc -include fvp-baser-aemv8r64.scc diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-standard.scc b/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-standard.scc deleted file mode 100644 index fd1fb28246..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64-standard.scc +++ /dev/null @@ -1,7 +0,0 @@ -define KMACHINE fvp-baser-aemv8r64 -define KTYPE standard -define KARCH arm64 - -include ktypes/standard/standard.scc - -include fvp-baser-aemv8r64.scc diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64.scc b/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64.scc deleted file mode 100644 index a8d796702c..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/arm-platforms-kmeta/bsp/arm-platforms/fvp-baser-aemv8r64.scc +++ /dev/null @@ -1,4 +0,0 @@ -kconf hardware arm64.cfg -kconf hardware fvp-common-peripherals.cfg -include cfg/virtio.scc -include virtio-9p.scc diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0002-Add-external-system-driver.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0002-Add-external-system-driver.patch index 5af041ef5e..d8d9488bcb 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0002-Add-external-system-driver.patch +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0002-Add-external-system-driver.patch @@ -1,7 +1,7 @@ -From 19eabe2a5fb97530820dd2a22fe6bc143a8d693f Mon Sep 17 00:00:00 2001 +From 9eac502eacd36a4975ec34a3f076594fa4364032 Mon Sep 17 00:00:00 2001 From: Emekcan Date: Fri, 19 Aug 2022 14:51:08 +0100 -Subject: [PATCH 2/6] Add external system driver +Subject: [PATCH] Add external system driver Adds external system driver to control it from user-space. It provides run and reset @@ -22,24 +22,26 @@ Signed-off-by: Rui Miguel Silva create mode 100644 drivers/misc/arm/extsys_ctrl.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 358ad56f6524..fd8654ffdab0 100644 +index 433aa4197785..912986abc46c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -514,4 +514,5 @@ source "drivers/misc/habanalabs/Kconfig" +@@ -555,4 +555,5 @@ source "drivers/misc/cardreader/Kconfig" source "drivers/misc/uacce/Kconfig" source "drivers/misc/pvpanic/Kconfig" source "drivers/misc/mchp_pci1xxxx/Kconfig" +source "drivers/misc/arm/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index ac9b3e757ba1..f7852e4fd63d 100644 +index 56de43943cd5..22e6561b8192 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile -@@ -62,3 +62,4 @@ obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o +@@ -63,5 +63,6 @@ obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o obj-$(CONFIG_OPEN_DICE) += open-dice.o obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/ obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o +obj-y += arm/ + obj-$(CONFIG_TMR_MANAGER) += xilinx_tmr_manager.o + obj-$(CONFIG_TMR_INJECT) += xilinx_tmr_inject.o diff --git a/drivers/misc/arm/Kconfig b/drivers/misc/arm/Kconfig new file mode 100644 index 000000000000..9f1eb284e530 @@ -216,6 +218,3 @@ index 000000000000..7929070ff43d +MODULE_DESCRIPTION("Arm External System Control Driver"); +MODULE_AUTHOR("Morten Borup Petersen"); +MODULE_AUTHOR("Rui Miguel Silva "); --- -2.39.0 - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0003-Add-rpmsg-driver-for-corstone1000.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0003-Add-rpmsg-driver-for-corstone1000.patch index 349042945b..cd9cec2700 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0003-Add-rpmsg-driver-for-corstone1000.patch +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0003-Add-rpmsg-driver-for-corstone1000.patch @@ -1,7 +1,7 @@ -From 9fb971c23d423f593620ed82fb69a7e2cd35986a Mon Sep 17 00:00:00 2001 +From a834f4e143ff647e7677dc60ab57ee5883f3ac8f Mon Sep 17 00:00:00 2001 From: Emekcan Date: Wed, 17 Aug 2022 14:21:42 +0100 -Subject: [PATCH 3/6] Add rpmsg driver for corstone1000 +Subject: [PATCH] Add rpmsg driver for corstone1000 Adds rpmsg driver to communicate with external system in corstone1000 platform. @@ -216,6 +216,3 @@ index 000000000000..4a80102669f6 +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ARM RPMSG Driver"); +MODULE_AUTHOR("Tushar Khandelwal "); --- -2.39.0 - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0004-rpmsg-arm-fix-return-value.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0004-rpmsg-arm-fix-return-value.patch index 5e70c00e93..516dbd7052 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0004-rpmsg-arm-fix-return-value.patch +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0004-rpmsg-arm-fix-return-value.patch @@ -1,7 +1,7 @@ -From ce77351c8ae6b04070135fdaedaad337bb0b4ef5 Mon Sep 17 00:00:00 2001 +From c1ffd793062a13afdcc07d4bc1a8007188bfca5f Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Tue, 27 Sep 2022 10:05:27 +0100 -Subject: [PATCH 4/6] rpmsg: arm: fix return value +Subject: [PATCH] rpmsg: arm: fix return value The creation of and endpoint returns a pointer, fix the return value to the right type. @@ -28,6 +28,3 @@ index 4a80102669f6..5c0dcc8e353d 100644 } return &channel->ept; --- -2.39.0 - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0005-rpmsg-arm-update-chrdev-to-ctrldev-registration.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0005-rpmsg-arm-update-chrdev-to-ctrldev-registration.patch index 852572ab0f..ef2eb7c130 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0005-rpmsg-arm-update-chrdev-to-ctrldev-registration.patch +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0005-rpmsg-arm-update-chrdev-to-ctrldev-registration.patch @@ -1,7 +1,7 @@ -From 590bf152e18b3cf7166c7accfc32ed3b2d07bf09 Mon Sep 17 00:00:00 2001 +From a8c295e1ff1d2b1032cc7495f212c56ba9f3e874 Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Tue, 27 Sep 2022 10:07:21 +0100 -Subject: [PATCH 5/6] rpmsg: arm: update chrdev to ctrldev registration +Subject: [PATCH] rpmsg: arm: update chrdev to ctrldev registration Since "rpmsg: Update rpmsg_chrdev_register_device function", there was a replacement of the chrdev driver to ctrldev @@ -26,6 +26,3 @@ index 5c0dcc8e353d..90bc8df90885 100644 } static const struct of_device_id client_of_match[] = { --- -2.39.0 - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0006-Adds-workaround-for-cs1k-specific-bug.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0006-Adds-workaround-for-cs1k-specific-bug.patch index 9956f26214..4fbeb23e5d 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0006-Adds-workaround-for-cs1k-specific-bug.patch +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/0006-Adds-workaround-for-cs1k-specific-bug.patch @@ -1,7 +1,7 @@ -From 00851c43f4d00e7451550660ab652e9ac9128e02 Mon Sep 17 00:00:00 2001 +From 555ac46f6f5157741a6fd8f21f74beb1340ed941 Mon Sep 17 00:00:00 2001 From: Emekcan Date: Thu, 13 Oct 2022 20:53:42 +0100 -Subject: [PATCH 6/6] Adds workaround for cs1k specific bug +Subject: [PATCH] Adds workaround for cs1k specific bug Adds a temporary workaround to solve a possible race-conditioning issue in the tee driver @@ -15,7 +15,7 @@ Signed-off-by: Rui Miguel Silva 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c -index d5e86ef40b89..cbb944f63321 100644 +index 2109cd178ff7..c15b3a83c720 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -32,6 +32,7 @@ @@ -26,7 +26,7 @@ index d5e86ef40b89..cbb944f63321 100644 #include "common.h" -@@ -362,7 +363,7 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit, +@@ -282,7 +283,7 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit, { u32 req_id, resp_id, src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); ffa_value_t ret; @@ -35,6 +35,3 @@ index d5e86ef40b89..cbb944f63321 100644 if (mode_32bit) { req_id = FFA_MSG_SEND_DIRECT_REQ; resp_id = FFA_MSG_SEND_DIRECT_RESP; --- -2.39.0 - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/fvp-baser-aemv8r64/fvp-baser-aemv8r64.dts b/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/fvp-baser-aemv8r64/fvp-baser-aemv8r64.dts deleted file mode 100644 index 6911a598f7..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/fvp-baser-aemv8r64/fvp-baser-aemv8r64.dts +++ /dev/null @@ -1,212 +0,0 @@ -/dts-v1/; - -/ { - - #address-cells = <0x2>; - #size-cells = <0x2>; - interrupt-parent = <0x1>; - model = "Generated"; - compatible = "arm,base"; - - memory@0 { - #address-cells = <0x2>; - #size-cells = <0x2>; - device_type = "memory"; - reg = <0x0 0x0 0x0 0x80000000>, - <0x00000008 0x80000000 0x0 0x80000000>; - }; - - cpus { - #address-cells = <0x2>; - #size-cells = <0x0>; - - cpu-map { - cluster0 { - core0 { thread0 { cpu = <&CPU_0>; }; }; - core1 { thread0 { cpu = <&CPU_1>; }; }; - core2 { thread0 { cpu = <&CPU_2>; }; }; - core3 { thread0 { cpu = <&CPU_3>; }; }; - }; - }; - - CPU_0: cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x7f800>; - }; - - CPU_1: cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x7f808>; - }; - - CPU_2: cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x7f810>; - }; - - CPU_3: cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x7f818>; - }; - }; - - interrupt-controller@af000000 { - compatible = "arm,gic-v3"; - #interrupt-cells = <0x3>; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - interrupt-controller; - #redistributor-regions = <0x1>; - reg = <0x0 0xaf000000 0x0 0x10000>, // GICD - <0x0 0xaf100000 0x0 0x100000>, // GICR - <0x0 0xac000000 0x0 0x2000>, // GICC - <0x0 0xac010000 0x0 0x2000>, // GICH - <0x0 0xac02f000 0x0 0x2000>; // GICV - interrupts = <0x1 9 0x4>; - linux,phandle = <0x1>; - phandle = <0x1>; - - its: msi-controller@2f020000 { - #msi-cells = <1>; - compatible = "arm,gic-v3-its"; - reg = <0x0 0xaf020000 0x0 0x20000>; // GITS - msi-controller; - }; - - }; - - refclk100mhz: refclk100mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <100000000>; - clock-output-names = "apb_pclk"; - }; - - refclk24mhz: refclk24mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "refclk24mhz"; - }; - - refclk1hz: refclk1hz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1>; - clock-output-names = "refclk1hz"; - }; - - uart@9c090000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0x9c090000 0x0 0x1000>; - interrupts = <0x0 5 0x4>; - clocks = <&refclk24mhz>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - uart@9c0a0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0x9c0a0000 0x0 0x1000>; - interrupts = <0x0 6 0x4>; - clocks = <&refclk24mhz>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - uart@9c0b0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0x9c0b0000 0x0 0x1000>; - interrupts = <0x0 7 0x4>; - clocks = <&refclk24mhz>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - uart@9c0c0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0x9c0c0000 0x0 0x1000>; - interrupts = <0x0 8 0x4>; - clocks = <&refclk24mhz>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - wdt@9c0f0000 { - compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0x9c0f0000 0x0 0x1000>; - interrupts = <0x0 0 0x4>; - clocks = <&refclk24mhz>, <&refclk100mhz>; - clock-names = "wdog_clk", "apb_pclk"; - }; - - rtc@9c170000 { - compatible = "arm,pl031", "arm,primecell"; - reg = <0x0 0x9c170000 0x0 0x1000>; - interrupts = <0x0 4 0x4>; - clocks = <&refclk1hz>; - clock-names = "apb_pclk"; - }; - - virtio-block@9c130000 { - compatible = "virtio,mmio"; - reg = <0 0x9c130000 0 0x200>; - interrupts = <0x0 42 0x4>; - }; - - virtio-p9@9c140000{ - compatible = "virtio,mmio"; - reg = <0x0 0x9c140000 0x0 0x1000>; - interrupts = <0x0 43 0x4>; - }; - - virtio-net@9c150000 { - compatible = "virtio,mmio"; - reg = <0 0x9c150000 0 0x200>; - interrupts = <0x0 44 0x4>; - }; - - virtio-rng@9c200000 { - compatible = "virtio,mmio"; - reg = <0 0x9c200000 0 0x200>; - interrupts = <0x0 46 0x4>; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <0x1 13 0xff08>, - <0x1 14 0xff08>, - <0x1 11 0xff08>, - <0x1 4 0xff08>; - clock-frequency = <100000000>; - }; - - aliases { - serial0 = "/uart@9c090000"; - serial1 = "/uart@9c0a0000"; - serial2 = "/uart@9c0b0000"; - serial3 = "/uart@9c0c0000"; - }; - - pmu { - compatible = "arm,armv8-pmuv3"; - interrupts = <0 60 4>, - <0 61 4>, - <0 62 4>, - <0 63 4>; - }; - - chosen { - bootargs = "earlycon console=ttyAMA0 loglevel=8 rootfstype=ext4 root=/dev/vda1 rw"; - stdout-path = "serial0"; - }; -}; diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc index b49ac800a2..4028cf31d1 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc @@ -14,7 +14,6 @@ ARMBSPFILESPATHS := "${THISDIR}:${THISDIR}/files:" # Arm platforms kmeta SRC_URI_KMETA = "file://arm-platforms-kmeta;type=kmeta;name=arm-platforms-kmeta;destsuffix=arm-platforms-kmeta" SRC_URI:append:fvp-base = " ${SRC_URI_KMETA}" -SRC_URI:append:fvp-baser-aemv8r64 = " ${SRC_URI_KMETA}" SRC_URI:append:juno = " ${SRC_URI_KMETA}" SRC_URI:append:n1sdp = " ${SRC_URI_KMETA}" SRCREV:arm-platforms-kmeta = "6147e82375aa9df8f2a162d42ea6406c79c854c5" @@ -58,13 +57,6 @@ KMACHINE:fvp-base = "fvp" FILESEXTRAPATHS:prepend:fvp-base := "${ARMBSPFILESPATHS}" SRC_URI:append:fvp-base = " file://0001-arm64-dts-fvp-Enable-virtio-rng-support.patch" -# -# FVP BaseR AEMv8r64 Machine -# -COMPATIBLE_MACHINE:fvp-baser-aemv8r64 = "fvp-baser-aemv8r64" -FILESEXTRAPATHS:prepend:fvp-baser-aemv8r64 := "${ARMBSPFILESPATHS}" -SRC_URI:append:fvp-baser-aemv8r64 = " file://fvp-baser-aemv8r64.dts;subdir=git/arch/arm64/boot/dts/arm" - # # Juno KMACHINE # @@ -80,7 +72,7 @@ COMPATIBLE_MACHINE:musca-s1 = "(^$)" # # N1SDP KMACHINE # -FILESEXTRAPATHS:prepend:n1sdp := "${THISDIR}/linux-yocto-6.1/n1sdp:" +FILESEXTRAPATHS:prepend:n1sdp := "${THISDIR}/linux-yocto-6.4/n1sdp:" COMPATIBLE_MACHINE:n1sdp = "n1sdp" KBUILD_DEFCONFIG:n1sdp = "defconfig" KCONFIG_MODE:n1sdp = "--alldefconfig" diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch deleted file mode 100644 index d7a47c654d..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 32ae4539865e64bcfb0c6955bdac8db5904e493d Mon Sep 17 00:00:00 2001 -From: Manoj Kumar -Date: Mon, 1 Feb 2021 21:36:43 +0530 -Subject: [PATCH] iommu/arm-smmu-v3: workaround for ATC_INV_SIZE_ALL in N1SDP - -ATC_INV_SIZE_ALL request should automatically translate to ATS -address which is not happening in SMMUv3 version gone into -N1SDP platform. This workaround manually sets the ATS address -field to proper value for ATC_INV_SIZE_ALL command. - -Change-Id: If89465be94720a62be85e1e6612f17e93fa9b8a5 -Signed-off-by: Manoj Kumar -Signed-off-by: Khasim Syed Mohammed - -Upstream-Status: Inappropriate [Workaround] -Signed-off-by: Manoj Kumar -Signed-off-by: Vishnu Banavath -Signed-off-by: Adam Johnston ---- - drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 + - drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -index d4d8bfee9feb..0524bf2ec021 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -@@ -1738,6 +1738,7 @@ arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size, - }; - - if (!size) { -+ cmd->atc.addr = ATC_INV_ADDR_ALL; - cmd->atc.size = ATC_INV_SIZE_ALL; - return; - } -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -index cd48590ada30..20892b2bfe1d 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -@@ -472,6 +472,7 @@ struct arm_smmu_cmdq_ent { - - #define CMDQ_OP_ATC_INV 0x40 - #define ATC_INV_SIZE_ALL 52 -+ #define ATC_INV_ADDR_ALL 0x7FFFFFFFFFFFF000UL - struct { - u32 sid; - u32 ssid; diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch deleted file mode 100644 index cb72ed0a07..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch +++ /dev/null @@ -1,159 +0,0 @@ -From fc8605e74b51d9e0ab8efd0489eca2e11d807f07 Mon Sep 17 00:00:00 2001 -From: Manoj Kumar -Date: Tue, 31 Aug 2021 16:15:38 +0000 -Subject: [PATCH] n1sdp: pci_quirk: add acs override for PCI devices - -Patch taken from: -https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.4/acso.patch - -Change-Id: Ib926bf50524ce9990fbaa2f2f8670fe84bd571f9 -Signed-off-by: Manoj Kumar - -Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] -Signed-off-by: Khasim Syed Mohammed -Signed-off-by: Vishnu Banavath -Signed-off-by: Adam Johnston ---- - .../admin-guide/kernel-parameters.txt | 8 ++ - drivers/pci/quirks.c | 102 ++++++++++++++++++ - 2 files changed, 110 insertions(+) - -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 963cdaecabcb..8e94af513b9f 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -4162,6 +4162,14 @@ - nomsi [MSI] If the PCI_MSI kernel config parameter is - enabled, this kernel boot option can be used to - disable the use of MSI interrupts system-wide. -+ pcie_acs_override [PCIE] Override missing PCIe ACS support for -+ downstream -+ All downstream ports - full ACS capabilities -+ multfunction -+ All multifunction devices - multifunction ACS subset -+ id:nnnn:nnnn -+ Specfic device - full ACS capabilities -+ Specified as vid:did (vendor/device ID) in hex - noioapicquirk [APIC] Disable all boot interrupt quirks. - Safety option to keep boot IRQs enabled. This - should never be necessary. -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 285acc4aaccc..d6ebef1f30db 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -3612,6 +3612,107 @@ static void quirk_no_bus_reset(struct pci_dev *dev) - dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; - } - -+static bool acs_on_downstream; -+static bool acs_on_multifunction; -+ -+#define NUM_ACS_IDS 16 -+struct acs_on_id { -+ unsigned short vendor; -+ unsigned short device; -+}; -+static struct acs_on_id acs_on_ids[NUM_ACS_IDS]; -+static u8 max_acs_id; -+ -+static __init int pcie_acs_override_setup(char *p) -+{ -+ if (!p) -+ return -EINVAL; -+ -+ while (*p) { -+ if (!strncmp(p, "downstream", 10)) -+ acs_on_downstream = true; -+ if (!strncmp(p, "multifunction", 13)) -+ acs_on_multifunction = true; -+ if (!strncmp(p, "id:", 3)) { -+ char opt[5]; -+ int ret; -+ long val; -+ -+ if (max_acs_id >= NUM_ACS_IDS - 1) { -+ pr_warn("Out of PCIe ACS override slots (%d)\n", -+ NUM_ACS_IDS); -+ goto next; -+ } -+ -+ p += 3; -+ snprintf(opt, 5, "%s", p); -+ ret = kstrtol(opt, 16, &val); -+ if (ret) { -+ pr_warn("PCIe ACS ID parse error %d\n", ret); -+ goto next; -+ } -+ acs_on_ids[max_acs_id].vendor = val; -+ -+ p += strcspn(p, ":"); -+ if (*p != ':') { -+ pr_warn("PCIe ACS invalid ID\n"); -+ goto next; -+ } -+ -+ p++; -+ snprintf(opt, 5, "%s", p); -+ ret = kstrtol(opt, 16, &val); -+ if (ret) { -+ pr_warn("PCIe ACS ID parse error %d\n", ret); -+ goto next; -+ } -+ acs_on_ids[max_acs_id].device = val; -+ max_acs_id++; -+ } -+next: -+ p += strcspn(p, ","); -+ if (*p == ',') -+ p++; -+ } -+ -+ if (acs_on_downstream || acs_on_multifunction || max_acs_id) -+ pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n"); -+ -+ return 0; -+} -+early_param("pcie_acs_override", pcie_acs_override_setup); -+ -+static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags) -+{ -+ int i; -+ -+ /* Never override ACS for legacy devices or devices with ACS caps */ -+ if (!pci_is_pcie(dev) || -+ pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS)) -+ return -ENOTTY; -+ -+ for (i = 0; i < max_acs_id; i++) -+ if (acs_on_ids[i].vendor == dev->vendor && -+ acs_on_ids[i].device == dev->device) -+ return 1; -+ -+ switch (pci_pcie_type(dev)) { -+ case PCI_EXP_TYPE_DOWNSTREAM: -+ case PCI_EXP_TYPE_ROOT_PORT: -+ if (acs_on_downstream) -+ return 1; -+ break; -+ case PCI_EXP_TYPE_ENDPOINT: -+ case PCI_EXP_TYPE_UPSTREAM: -+ case PCI_EXP_TYPE_LEG_END: -+ case PCI_EXP_TYPE_RC_END: -+ if (acs_on_multifunction && dev->multifunction) -+ return 1; -+ } -+ -+ return -ENOTTY; -+} -+ - /* - * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be - * prevented for those affected devices. -@@ -4980,6 +5081,7 @@ static const struct pci_dev_acs_enabled { - { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, - /* Wangxun nics */ - { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, -+ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides }, - { 0 } - }; - diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch deleted file mode 100644 index 9b439e472d..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch +++ /dev/null @@ -1,324 +0,0 @@ -From 5aa5769af625c79589fd84b8afc06149c2362218 Mon Sep 17 00:00:00 2001 -From: Deepak Pandey -Date: Fri, 31 May 2019 16:42:43 +0100 -Subject: [PATCH] pcie: Add quirk for the Arm Neoverse N1SDP platform - -The Arm N1SDP SoC suffers from some PCIe integration issues, most -prominently config space accesses to not existing BDFs being answered -with a bus abort, resulting in an SError. -To mitigate this, the firmware scans the bus before boot (catching the -SErrors) and creates a table with valid BDFs, which acts as a filter for -Linux' config space accesses. - -Add code consulting the table as an ACPI PCIe quirk, also register the -corresponding device tree based description of the host controller. -Also fix the other two minor issues on the way, namely not being fully -ECAM compliant and config space accesses being restricted to 32-bit -accesses only. - -This allows the Arm Neoverse N1SDP board to boot Linux without crashing -and to access *any* devices (there are no platform devices except UART). - -Signed-off-by: Deepak Pandey -[Sudipto: extend to cover the CCIX root port as well] -Signed-off-by: Sudipto Paul -[Andre: fix coding style issues, rewrite some parts, add DT support] -Signed-off-by: Andre Przywara - -Change-Id: I1d3a4b9bf6b3b883d262e3c4ff1f88a0eb81c1fe -Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] -Signed-off-by: Deepak Pandey -Signed-off-by: Vishnu Banavath -Signed-off-by: Adam Johnston ---- - arch/arm64/configs/defconfig | 1 + - drivers/acpi/pci_mcfg.c | 7 + - drivers/pci/controller/Kconfig | 11 ++ - drivers/pci/controller/Makefile | 2 +- - drivers/pci/controller/pcie-n1sdp.c | 198 ++++++++++++++++++++++++++++ - include/linux/pci-ecam.h | 2 + - 6 files changed, 220 insertions(+), 1 deletion(-) - create mode 100644 drivers/pci/controller/pcie-n1sdp.c - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index bbbc31391a65..973aa3b4d407 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -214,6 +214,7 @@ CONFIG_NFC_S3FWRN5_I2C=m - CONFIG_PCI=y - CONFIG_PCIEPORTBUS=y - CONFIG_PCIEAER=y -+CONFIG_PCI_QUIRKS=y - CONFIG_PCI_IOV=y - CONFIG_PCI_PASID=y - CONFIG_HOTPLUG_PCI=y -diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c -index 860014b89b8e..2d4c1c699ffe 100644 ---- a/drivers/acpi/pci_mcfg.c -+++ b/drivers/acpi/pci_mcfg.c -@@ -171,6 +171,13 @@ static struct mcfg_fixup mcfg_quirks[] = { - ALTRA_ECAM_QUIRK(1, 13), - ALTRA_ECAM_QUIRK(1, 14), - ALTRA_ECAM_QUIRK(1, 15), -+ -+#define N1SDP_ECAM_MCFG(rev, seg, ops) \ -+ {"ARMLTD", "ARMN1SDP", rev, seg, MCFG_BUS_ANY, ops } -+ -+ /* N1SDP SoC with v1 PCIe controller */ -+ N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops), -+ N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops), - #endif /* ARM64 */ - - #ifdef CONFIG_LOONGARCH -diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig -index bfd9bac37e24..7a65799dded7 100644 ---- a/drivers/pci/controller/Kconfig -+++ b/drivers/pci/controller/Kconfig -@@ -50,6 +50,17 @@ config PCI_IXP4XX - Say Y here if you want support for the PCI host controller found - in the Intel IXP4xx XScale-based network processor SoC. - -+config PCIE_HOST_N1SDP_ECAM -+ bool "ARM N1SDP PCIe Controller" -+ depends on ARM64 -+ depends on OF || (ACPI && PCI_QUIRKS) -+ select PCI_HOST_COMMON -+ default y if ARCH_VEXPRESS -+ help -+ Say Y here if you want PCIe support for the Arm N1SDP platform. -+ The controller is ECAM compliant, but needs a quirk to workaround -+ an integration issue. -+ - config PCI_TEGRA - bool "NVIDIA Tegra PCIe controller" - depends on ARCH_TEGRA || COMPILE_TEST -diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile -index 37c8663de7fe..08e5afcf6e86 100644 ---- a/drivers/pci/controller/Makefile -+++ b/drivers/pci/controller/Makefile -@@ -39,7 +39,7 @@ obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o - obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o - obj-$(CONFIG_PCIE_APPLE) += pcie-apple.o - obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o -- -+obj-$(CONFIG_PCIE_HOST_N1SDP_ECAM) += pcie-n1sdp.o - # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW - obj-y += dwc/ - obj-y += mobiveil/ -diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c -new file mode 100644 -index 000000000000..408699b9dcb1 ---- /dev/null -+++ b/drivers/pci/controller/pcie-n1sdp.c -@@ -0,0 +1,198 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2018/2019 ARM Ltd. -+ * -+ * This quirk is to mask the following issues: -+ * - PCIE SLVERR: config space accesses to invalid PCIe BDFs cause a bus -+ * error (signalled as an asynchronous SError) -+ * - MCFG BDF mapping: the root complex is mapped separately from the device -+ * config space -+ * - Non 32-bit accesses to config space are not supported. -+ * -+ * At boot time the SCP board firmware creates a discovery table with -+ * the root complex' base address and the valid BDF values, discovered while -+ * scanning the config space and catching the SErrors. -+ * Linux responds only to the EPs listed in this table, returning NULL -+ * for the rest. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../pci.h" -+ -+/* Platform specific values as hardcoded in the firmware. */ -+#define AP_NS_SHARED_MEM_BASE 0x06000000 -+#define MAX_SEGMENTS 2 /* Two PCIe root complexes. */ -+#define BDF_TABLE_SIZE SZ_16K -+ -+/* -+ * Shared memory layout as written by the SCP upon boot time: -+ * ---- -+ * Discover data header --> RC base address -+ * \-> BDF Count -+ * Discover data --> BDF 0...n -+ * ---- -+ */ -+struct pcie_discovery_data { -+ u32 rc_base_addr; -+ u32 nr_bdfs; -+ u32 valid_bdfs[0]; -+} *pcie_discovery_data[MAX_SEGMENTS]; -+ -+void __iomem *rc_remapped_addr[MAX_SEGMENTS]; -+ -+/* -+ * map_bus() is called before we do a config space access for a certain -+ * device. We use this to check whether this device is valid, avoiding -+ * config space accesses which would result in an SError otherwise. -+ */ -+static void __iomem *pci_n1sdp_map_bus(struct pci_bus *bus, unsigned int devfn, -+ int where) -+{ -+ struct pci_config_window *cfg = bus->sysdata; -+ unsigned int devfn_shift = cfg->ops->bus_shift - 8; -+ unsigned int busn = bus->number; -+ unsigned int segment = bus->domain_nr; -+ unsigned int bdf_addr; -+ unsigned int table_count, i; -+ struct pci_dev *dev; -+ -+ if (segment >= MAX_SEGMENTS || -+ busn < cfg->busr.start || busn > cfg->busr.end) -+ return NULL; -+ -+ /* The PCIe root complex has a separate config space mapping. */ -+ if (busn == 0 && devfn == 0) -+ return rc_remapped_addr[segment] + where; -+ -+ dev = pci_get_domain_bus_and_slot(segment, busn, devfn); -+ if (dev && dev->is_virtfn) -+ return pci_ecam_map_bus(bus, devfn, where); -+ -+ /* Accesses beyond the vendor ID always go to existing devices. */ -+ if (where > 0) -+ return pci_ecam_map_bus(bus, devfn, where); -+ -+ busn -= cfg->busr.start; -+ bdf_addr = (busn << cfg->ops->bus_shift) + (devfn << devfn_shift); -+ table_count = pcie_discovery_data[segment]->nr_bdfs; -+ for (i = 0; i < table_count; i++) { -+ if (bdf_addr == pcie_discovery_data[segment]->valid_bdfs[i]) -+ return pci_ecam_map_bus(bus, devfn, where); -+ } -+ -+ return NULL; -+} -+ -+static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) -+{ -+ phys_addr_t table_base; -+ struct device *dev = cfg->parent; -+ struct pcie_discovery_data *shared_data; -+ size_t bdfs_size; -+ -+ if (segment >= MAX_SEGMENTS) -+ return -ENODEV; -+ -+ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; -+ -+ if (!request_mem_region(table_base, BDF_TABLE_SIZE, -+ "PCIe valid BDFs")) { -+ dev_err(dev, "PCIe BDF shared region request failed\n"); -+ return -ENOMEM; -+ } -+ -+ shared_data = devm_ioremap(dev, -+ table_base, BDF_TABLE_SIZE); -+ if (!shared_data) -+ return -ENOMEM; -+ -+ /* Copy the valid BDFs structure to allocated normal memory. */ -+ bdfs_size = sizeof(struct pcie_discovery_data) + -+ sizeof(u32) * shared_data->nr_bdfs; -+ pcie_discovery_data[segment] = devm_kmalloc(dev, bdfs_size, GFP_KERNEL); -+ if (!pcie_discovery_data[segment]) -+ return -ENOMEM; -+ -+ memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size); -+ -+ rc_remapped_addr[segment] = devm_ioremap(dev, -+ shared_data->rc_base_addr, -+ PCI_CFG_SPACE_EXP_SIZE); -+ if (!rc_remapped_addr[segment]) { -+ dev_err(dev, "Cannot remap root port base\n"); -+ return -ENOMEM; -+ } -+ -+ devm_iounmap(dev, shared_data); -+ -+ return 0; -+} -+ -+/* Called for ACPI segment 0, and for all segments when using DT. */ -+static int pci_n1sdp_pcie_init(struct pci_config_window *cfg) -+{ -+ struct platform_device *pdev = to_platform_device(cfg->parent); -+ int segment = 0; -+ -+ if (pdev->dev.of_node) -+ segment = of_get_pci_domain_nr(pdev->dev.of_node); -+ if (segment < 0 || segment > MAX_SEGMENTS) { -+ dev_err(&pdev->dev, "N1SDP PCI controllers require linux,pci-domain property\n"); -+ dev_err(&pdev->dev, "Or invalid segment number, must be smaller than %d\n", -+ MAX_SEGMENTS); -+ return -EINVAL; -+ } -+ -+ return pci_n1sdp_init(cfg, segment); -+} -+ -+/* Called for ACPI segment 1. */ -+static int pci_n1sdp_ccix_init(struct pci_config_window *cfg) -+{ -+ return pci_n1sdp_init(cfg, 1); -+} -+ -+const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = { -+ .bus_shift = 20, -+ .init = pci_n1sdp_pcie_init, -+ .pci_ops = { -+ .map_bus = pci_n1sdp_map_bus, -+ .read = pci_generic_config_read32, -+ .write = pci_generic_config_write32, -+ } -+}; -+ -+const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = { -+ .bus_shift = 20, -+ .init = pci_n1sdp_ccix_init, -+ .pci_ops = { -+ .map_bus = pci_n1sdp_map_bus, -+ .read = pci_generic_config_read32, -+ .write = pci_generic_config_write32, -+ } -+}; -+ -+static const struct of_device_id n1sdp_pcie_of_match[] = { -+ { .compatible = "arm,n1sdp-pcie", .data = &pci_n1sdp_pcie_ecam_ops }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, n1sdp_pcie_of_match); -+ -+static struct platform_driver n1sdp_pcie_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = n1sdp_pcie_of_match, -+ .suppress_bind_attrs = true, -+ }, -+ .probe = pci_host_common_probe, -+}; -+builtin_platform_driver(n1sdp_pcie_driver); -diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h -index 6b1301e2498e..b3cf3adeab28 100644 ---- a/include/linux/pci-ecam.h -+++ b/include/linux/pci-ecam.h -@@ -88,6 +88,8 @@ extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x - extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */ - extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ - extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ -+extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */ -+extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */ - #endif - - #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch deleted file mode 100644 index b804658b00..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch +++ /dev/null @@ -1,136 +0,0 @@ -From b59e0d6c6035db80fc9044df0333f96ede53ad7a Mon Sep 17 00:00:00 2001 -From: Sayanta Pattanayak -Date: Wed, 9 Feb 2022 20:37:43 +0530 -Subject: [PATCH] n1sdp: pcie: add quirk support enabling remote chip PCIe - -Base address mapping for remote chip Root PCIe ECAM space. - -When two N1SDP boards are coupled via the CCIX connection, the PCI host -complex of the remote board appears as PCIe segment 2 on the primary board. -The resources of the secondary board, including the host complex, are -mapped at offset 0x40000000000 into the address space of the primary -board, so take that into account when accessing the remote PCIe segment. - -Change-Id: I0e8d1eb119aef6444b9df854a39b24441c12195a -Signed-off-by: Sayanta Pattanayak -Signed-off-by: Khasim Syed Mohammed -Signed-off-by: Andre Przywara -Signed-off-by: sahil - -Upstream-Status: Inappropriate [will not be submitted as its an hack required to fix the hardware issue] -Signed-off-by: Sayanta Pattanayak -Signed-off-by: Vishnu Banavath -Signed-off-by: Adam Johnston ---- - drivers/acpi/pci_mcfg.c | 1 + - drivers/pci/controller/pcie-n1sdp.c | 32 +++++++++++++++++++++++++---- - include/linux/pci-ecam.h | 1 + - 3 files changed, 30 insertions(+), 4 deletions(-) - -diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c -index 2d4c1c699ffe..27f1e9a45c17 100644 ---- a/drivers/acpi/pci_mcfg.c -+++ b/drivers/acpi/pci_mcfg.c -@@ -178,6 +178,7 @@ static struct mcfg_fixup mcfg_quirks[] = { - /* N1SDP SoC with v1 PCIe controller */ - N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops), - N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops), -+ N1SDP_ECAM_MCFG(0x20181101, 2, &pci_n1sdp_remote_pcie_ecam_ops), - #endif /* ARM64 */ - - #ifdef CONFIG_LOONGARCH -diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c -index 408699b9dcb1..b3b02417fd7d 100644 ---- a/drivers/pci/controller/pcie-n1sdp.c -+++ b/drivers/pci/controller/pcie-n1sdp.c -@@ -30,8 +30,10 @@ - - /* Platform specific values as hardcoded in the firmware. */ - #define AP_NS_SHARED_MEM_BASE 0x06000000 --#define MAX_SEGMENTS 2 /* Two PCIe root complexes. */ -+/* Two PCIe root complexes in One Chip + One PCIe RC in Remote Chip */ -+#define MAX_SEGMENTS 3 - #define BDF_TABLE_SIZE SZ_16K -+#define REMOTE_CHIP_ADDR_OFFSET 0x40000000000 - - /* - * Shared memory layout as written by the SCP upon boot time: -@@ -97,12 +99,17 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) - phys_addr_t table_base; - struct device *dev = cfg->parent; - struct pcie_discovery_data *shared_data; -- size_t bdfs_size; -+ size_t bdfs_size, rc_base_addr = 0; - - if (segment >= MAX_SEGMENTS) - return -ENODEV; - -- table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; -+ if (segment > 1) { -+ rc_base_addr = REMOTE_CHIP_ADDR_OFFSET; -+ table_base = AP_NS_SHARED_MEM_BASE + REMOTE_CHIP_ADDR_OFFSET; -+ } else { -+ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; -+ } - - if (!request_mem_region(table_base, BDF_TABLE_SIZE, - "PCIe valid BDFs")) { -@@ -114,6 +121,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) - table_base, BDF_TABLE_SIZE); - if (!shared_data) - return -ENOMEM; -+ rc_base_addr += shared_data->rc_base_addr; - - /* Copy the valid BDFs structure to allocated normal memory. */ - bdfs_size = sizeof(struct pcie_discovery_data) + -@@ -125,7 +133,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) - memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size); - - rc_remapped_addr[segment] = devm_ioremap(dev, -- shared_data->rc_base_addr, -+ rc_base_addr, - PCI_CFG_SPACE_EXP_SIZE); - if (!rc_remapped_addr[segment]) { - dev_err(dev, "Cannot remap root port base\n"); -@@ -161,6 +169,12 @@ static int pci_n1sdp_ccix_init(struct pci_config_window *cfg) - return pci_n1sdp_init(cfg, 1); - } - -+/* Called for ACPI segment 2. */ -+static int pci_n1sdp_remote_pcie_init(struct pci_config_window *cfg) -+{ -+ return pci_n1sdp_init(cfg, 2); -+} -+ - const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = { - .bus_shift = 20, - .init = pci_n1sdp_pcie_init, -@@ -181,6 +195,16 @@ const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = { - } - }; - -+const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops = { -+ .bus_shift = 20, -+ .init = pci_n1sdp_remote_pcie_init, -+ .pci_ops = { -+ .map_bus = pci_n1sdp_map_bus, -+ .read = pci_generic_config_read32, -+ .write = pci_generic_config_write32, -+ } -+}; -+ - static const struct of_device_id n1sdp_pcie_of_match[] = { - { .compatible = "arm,n1sdp-pcie", .data = &pci_n1sdp_pcie_ecam_ops }, - { }, -diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h -index b3cf3adeab28..d4316795c00d 100644 ---- a/include/linux/pci-ecam.h -+++ b/include/linux/pci-ecam.h -@@ -90,6 +90,7 @@ extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ - extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ - extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */ - extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */ -+extern const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops; /* Arm N1SDP PCIe */ - #endif - - #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch deleted file mode 100644 index cc9d87170f..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ff02f77788f8c01e9d675912c063e89415804b7d Mon Sep 17 00:00:00 2001 -From: Andre Przywara -Date: Fri, 17 May 2019 17:39:27 +0100 -Subject: [PATCH] arm64: kpti: Whitelist early Arm Neoverse N1 revisions - -Early revisions (r1p0) of the Neoverse N1 core did not feature the -CSV3 field in ID_AA64PFR0_EL1 to advertise they are not affected by -the Spectre variant 3 (aka Meltdown) vulnerability. - -Add this particular revision to the whitelist to avoid enabling KPTI. - -Signed-off-by: Andre Przywara -Change-Id: I78df055a3e674aefd195d41cc6dc4ee08b0af099 -Upstream-Status: Inappropriate -Signed-off-by: Andre Przywara -Signed-off-by: Vishnu Banavath -Signed-off-by: Adam Johnston ---- - arch/arm64/kernel/cpufeature.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index b3f37e2209ad..b74210f38cd8 100644 ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -1646,6 +1646,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, - MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER), - MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), - MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), -+ MIDR_REV(MIDR_NEOVERSE_N1, 1, 0), /* missing CSV3 */ - { /* sentinel */ } - }; - char const *str = "kpti command line option"; diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch deleted file mode 100644 index 8aea1f60d7..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 330a620b5c73505e62a2e0accc155fbc78859cee Mon Sep 17 00:00:00 2001 -From: Vishnu Banavath -Date: Wed, 21 Sep 2022 15:54:14 +0100 -Subject: [PATCH] arm64: defconfig: disable config options that does not apply - anymore - -Following config options should be not set to be more accurate and -works with build system like yocto -CONFIG_BT_HCIUART_MRVL -CONFIG_BT_MRVL -CONFIG_BT_MRVL_SDIO -CONFIG_BT_QCOMSMD - -Upstream-Status: Pending [not submitted upstream yet] -Signed-off-by: Adam Johnston -Signed-off-by: Vishnu Banavath ---- - arch/arm64/configs/defconfig | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 973aa3b4d407..61f040394a2d 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -198,10 +198,10 @@ CONFIG_BT_HCIUART=m - CONFIG_BT_HCIUART_LL=y - CONFIG_BT_HCIUART_BCM=y - CONFIG_BT_HCIUART_QCA=y --CONFIG_BT_HCIUART_MRVL=y --CONFIG_BT_MRVL=m --CONFIG_BT_MRVL_SDIO=m --CONFIG_BT_QCOMSMD=m -+# CONFIG_BT_HCIUART_MRVL is not set -+# CONFIG_BT_MRVL is not set -+# CONFIG_BT_MRVL_SDIO is not set -+# CONFIG_BT_QCOMSMD is not set - CONFIG_CFG80211=m - CONFIG_MAC80211=m - CONFIG_MAC80211_LEDS=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-nvme.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-nvme.cfg deleted file mode 100644 index 268103555e..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-nvme.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# Enable NVMe flash storage support -CONFIG_NVME_CORE=y -CONFIG_BLK_DEV_NVME=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-realtek-R8169.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-realtek-R8169.cfg deleted file mode 100644 index 7a5747407c..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-realtek-R8169.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# Enable Realtek Gigabit Ethernet adapter -CONFIG_REALTEK_PHY=y -CONFIG_R8169=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-usb_conn_gpio.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-usb_conn_gpio.cfg deleted file mode 100644 index 128c902710..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/enable-usb_conn_gpio.cfg +++ /dev/null @@ -1,2 +0,0 @@ -# PHY_TEGRA_XUSB sets this to y, but its set as m in defconfig -CONFIG_USB_CONN_GPIO=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/usb_xhci_pci_renesas.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/usb_xhci_pci_renesas.cfg deleted file mode 100644 index c06507c060..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.1/n1sdp/usb_xhci_pci_renesas.cfg +++ /dev/null @@ -1,2 +0,0 @@ -# CONFIG_USB_XHCI_PCI is not set -# CONFIG_USB_XHCI_PCI_RENESAS is not set diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch new file mode 100644 index 0000000000..869ca6f798 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0001-iommu-arm-smmu-v3-workaround-for-ATC_INV_SIZE_ALL-in.patch @@ -0,0 +1,47 @@ +From ec84afa8e74bc5df8b5794eef8f29b097adc7cb3 Mon Sep 17 00:00:00 2001 +From: Manoj Kumar +Date: Mon, 1 Feb 2021 21:36:43 +0530 +Subject: [PATCH] iommu/arm-smmu-v3: workaround for ATC_INV_SIZE_ALL in N1SDP + +ATC_INV_SIZE_ALL request should automatically translate to ATS +address which is not happening in SMMUv3 version gone into +N1SDP platform. This workaround manually sets the ATS address +field to proper value for ATC_INV_SIZE_ALL command. + +Change-Id: If89465be94720a62be85e1e6612f17e93fa9b8a5 +Signed-off-by: Manoj Kumar +Signed-off-by: Khasim Syed Mohammed + +Upstream-Status: Inappropriate [Workaround] +Signed-off-by: Manoj Kumar +Signed-off-by: Vishnu Banavath +Signed-off-by: Adam Johnston +--- + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 + + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +index 3fd83fb75722..852ed05b14a3 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -1747,6 +1747,7 @@ arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size, + }; + + if (!size) { ++ cmd->atc.addr = ATC_INV_ADDR_ALL; + cmd->atc.size = ATC_INV_SIZE_ALL; + return; + } +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +index b574c58a3487..018086b65381 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +@@ -472,6 +472,7 @@ struct arm_smmu_cmdq_ent { + + #define CMDQ_OP_ATC_INV 0x40 + #define ATC_INV_SIZE_ALL 52 ++ #define ATC_INV_ADDR_ALL 0x7FFFFFFFFFFFF000UL + struct { + u32 sid; + u32 ssid; diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch new file mode 100644 index 0000000000..9bf8112bf0 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0002-n1sdp-pci_quirk-add-acs-override-for-PCI-devices.patch @@ -0,0 +1,159 @@ +From 9761e48b2d6904a58996fcaadcf25684482a72c8 Mon Sep 17 00:00:00 2001 +From: Manoj Kumar +Date: Tue, 31 Aug 2021 16:15:38 +0000 +Subject: [PATCH] n1sdp: pci_quirk: add acs override for PCI devices + +Patch taken from: +https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.4/acso.patch + +Change-Id: Ib926bf50524ce9990fbaa2f2f8670fe84bd571f9 +Signed-off-by: Manoj Kumar + +Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] +Signed-off-by: Khasim Syed Mohammed +Signed-off-by: Vishnu Banavath +Signed-off-by: Adam Johnston +--- + .../admin-guide/kernel-parameters.txt | 8 ++ + drivers/pci/quirks.c | 102 ++++++++++++++++++ + 2 files changed, 110 insertions(+) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 9e5bab29685f..7ee740a37e5d 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4235,6 +4235,14 @@ + nomsi [MSI] If the PCI_MSI kernel config parameter is + enabled, this kernel boot option can be used to + disable the use of MSI interrupts system-wide. ++ pcie_acs_override [PCIE] Override missing PCIe ACS support for ++ downstream ++ All downstream ports - full ACS capabilities ++ multfunction ++ All multifunction devices - multifunction ACS subset ++ id:nnnn:nnnn ++ Specfic device - full ACS capabilities ++ Specified as vid:did (vendor/device ID) in hex + noioapicquirk [APIC] Disable all boot interrupt quirks. + Safety option to keep boot IRQs enabled. This + should never be necessary. +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index b7c65193e786..16b81d1ccafa 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3625,6 +3625,107 @@ static void quirk_no_bus_reset(struct pci_dev *dev) + dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; + } + ++static bool acs_on_downstream; ++static bool acs_on_multifunction; ++ ++#define NUM_ACS_IDS 16 ++struct acs_on_id { ++ unsigned short vendor; ++ unsigned short device; ++}; ++static struct acs_on_id acs_on_ids[NUM_ACS_IDS]; ++static u8 max_acs_id; ++ ++static __init int pcie_acs_override_setup(char *p) ++{ ++ if (!p) ++ return -EINVAL; ++ ++ while (*p) { ++ if (!strncmp(p, "downstream", 10)) ++ acs_on_downstream = true; ++ if (!strncmp(p, "multifunction", 13)) ++ acs_on_multifunction = true; ++ if (!strncmp(p, "id:", 3)) { ++ char opt[5]; ++ int ret; ++ long val; ++ ++ if (max_acs_id >= NUM_ACS_IDS - 1) { ++ pr_warn("Out of PCIe ACS override slots (%d)\n", ++ NUM_ACS_IDS); ++ goto next; ++ } ++ ++ p += 3; ++ snprintf(opt, 5, "%s", p); ++ ret = kstrtol(opt, 16, &val); ++ if (ret) { ++ pr_warn("PCIe ACS ID parse error %d\n", ret); ++ goto next; ++ } ++ acs_on_ids[max_acs_id].vendor = val; ++ ++ p += strcspn(p, ":"); ++ if (*p != ':') { ++ pr_warn("PCIe ACS invalid ID\n"); ++ goto next; ++ } ++ ++ p++; ++ snprintf(opt, 5, "%s", p); ++ ret = kstrtol(opt, 16, &val); ++ if (ret) { ++ pr_warn("PCIe ACS ID parse error %d\n", ret); ++ goto next; ++ } ++ acs_on_ids[max_acs_id].device = val; ++ max_acs_id++; ++ } ++next: ++ p += strcspn(p, ","); ++ if (*p == ',') ++ p++; ++ } ++ ++ if (acs_on_downstream || acs_on_multifunction || max_acs_id) ++ pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n"); ++ ++ return 0; ++} ++early_param("pcie_acs_override", pcie_acs_override_setup); ++ ++static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags) ++{ ++ int i; ++ ++ /* Never override ACS for legacy devices or devices with ACS caps */ ++ if (!pci_is_pcie(dev) || ++ pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS)) ++ return -ENOTTY; ++ ++ for (i = 0; i < max_acs_id; i++) ++ if (acs_on_ids[i].vendor == dev->vendor && ++ acs_on_ids[i].device == dev->device) ++ return 1; ++ ++ switch (pci_pcie_type(dev)) { ++ case PCI_EXP_TYPE_DOWNSTREAM: ++ case PCI_EXP_TYPE_ROOT_PORT: ++ if (acs_on_downstream) ++ return 1; ++ break; ++ case PCI_EXP_TYPE_ENDPOINT: ++ case PCI_EXP_TYPE_UPSTREAM: ++ case PCI_EXP_TYPE_LEG_END: ++ case PCI_EXP_TYPE_RC_END: ++ if (acs_on_multifunction && dev->multifunction) ++ return 1; ++ } ++ ++ return -ENOTTY; ++} ++ + /* + * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be + * prevented for those affected devices. +@@ -5017,6 +5118,7 @@ static const struct pci_dev_acs_enabled { + { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, + /* Wangxun nics */ + { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, ++ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides }, + { 0 } + }; + diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch new file mode 100644 index 0000000000..96d55ad8ff --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0003-pcie-Add-quirk-for-the-Arm-Neoverse-N1SDP-platform.patch @@ -0,0 +1,324 @@ +From 268bfbcd8f16660bf5fc8e31b18b4090743c6dbe Mon Sep 17 00:00:00 2001 +From: Deepak Pandey +Date: Fri, 31 May 2019 16:42:43 +0100 +Subject: [PATCH] pcie: Add quirk for the Arm Neoverse N1SDP platform + +The Arm N1SDP SoC suffers from some PCIe integration issues, most +prominently config space accesses to not existing BDFs being answered +with a bus abort, resulting in an SError. +To mitigate this, the firmware scans the bus before boot (catching the +SErrors) and creates a table with valid BDFs, which acts as a filter for +Linux' config space accesses. + +Add code consulting the table as an ACPI PCIe quirk, also register the +corresponding device tree based description of the host controller. +Also fix the other two minor issues on the way, namely not being fully +ECAM compliant and config space accesses being restricted to 32-bit +accesses only. + +This allows the Arm Neoverse N1SDP board to boot Linux without crashing +and to access *any* devices (there are no platform devices except UART). + +Signed-off-by: Deepak Pandey +[Sudipto: extend to cover the CCIX root port as well] +Signed-off-by: Sudipto Paul +[Andre: fix coding style issues, rewrite some parts, add DT support] +Signed-off-by: Andre Przywara + +Change-Id: I1d3a4b9bf6b3b883d262e3c4ff1f88a0eb81c1fe +Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] +Signed-off-by: Deepak Pandey +Signed-off-by: Vishnu Banavath +Signed-off-by: Adam Johnston +--- + arch/arm64/configs/defconfig | 1 + + drivers/acpi/pci_mcfg.c | 7 + + drivers/pci/controller/Kconfig | 11 ++ + drivers/pci/controller/Makefile | 2 +- + drivers/pci/controller/pcie-n1sdp.c | 198 ++++++++++++++++++++++++++++ + include/linux/pci-ecam.h | 2 + + 6 files changed, 220 insertions(+), 1 deletion(-) + create mode 100644 drivers/pci/controller/pcie-n1sdp.c + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index a24609e14d50..cd73d1704dd2 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -203,6 +203,7 @@ CONFIG_NFC_S3FWRN5_I2C=m + CONFIG_PCI=y + CONFIG_PCIEPORTBUS=y + CONFIG_PCIEAER=y ++CONFIG_PCI_QUIRKS=y + CONFIG_PCI_IOV=y + CONFIG_PCI_PASID=y + CONFIG_HOTPLUG_PCI=y +diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c +index 860014b89b8e..2d4c1c699ffe 100644 +--- a/drivers/acpi/pci_mcfg.c ++++ b/drivers/acpi/pci_mcfg.c +@@ -171,6 +171,13 @@ static struct mcfg_fixup mcfg_quirks[] = { + ALTRA_ECAM_QUIRK(1, 13), + ALTRA_ECAM_QUIRK(1, 14), + ALTRA_ECAM_QUIRK(1, 15), ++ ++#define N1SDP_ECAM_MCFG(rev, seg, ops) \ ++ {"ARMLTD", "ARMN1SDP", rev, seg, MCFG_BUS_ANY, ops } ++ ++ /* N1SDP SoC with v1 PCIe controller */ ++ N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops), ++ N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops), + #endif /* ARM64 */ + + #ifdef CONFIG_LOONGARCH +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 8d49bad7f847..7bb49afbcd5b 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -21,6 +21,17 @@ config PCIE_ALTERA + Say Y here if you want to enable PCIe controller support on Altera + FPGA. + ++config PCIE_HOST_N1SDP_ECAM ++ bool "ARM N1SDP PCIe Controller" ++ depends on ARM64 ++ depends on OF || (ACPI && PCI_QUIRKS) ++ select PCI_HOST_COMMON ++ default y if ARCH_VEXPRESS ++ help ++ Say Y here if you want PCIe support for the Arm N1SDP platform. ++ The controller is ECAM compliant, but needs a quirk to workaround ++ an integration issue. ++ + config PCIE_ALTERA_MSI + tristate "Altera PCIe MSI feature" + depends on PCIE_ALTERA +diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile +index 37c8663de7fe..08e5afcf6e86 100644 +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -39,7 +39,7 @@ obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o + obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o + obj-$(CONFIG_PCIE_APPLE) += pcie-apple.o + obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o +- ++obj-$(CONFIG_PCIE_HOST_N1SDP_ECAM) += pcie-n1sdp.o + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ + obj-y += mobiveil/ +diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c +new file mode 100644 +index 000000000000..408699b9dcb1 +--- /dev/null ++++ b/drivers/pci/controller/pcie-n1sdp.c +@@ -0,0 +1,198 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018/2019 ARM Ltd. ++ * ++ * This quirk is to mask the following issues: ++ * - PCIE SLVERR: config space accesses to invalid PCIe BDFs cause a bus ++ * error (signalled as an asynchronous SError) ++ * - MCFG BDF mapping: the root complex is mapped separately from the device ++ * config space ++ * - Non 32-bit accesses to config space are not supported. ++ * ++ * At boot time the SCP board firmware creates a discovery table with ++ * the root complex' base address and the valid BDF values, discovered while ++ * scanning the config space and catching the SErrors. ++ * Linux responds only to the EPs listed in this table, returning NULL ++ * for the rest. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../pci.h" ++ ++/* Platform specific values as hardcoded in the firmware. */ ++#define AP_NS_SHARED_MEM_BASE 0x06000000 ++#define MAX_SEGMENTS 2 /* Two PCIe root complexes. */ ++#define BDF_TABLE_SIZE SZ_16K ++ ++/* ++ * Shared memory layout as written by the SCP upon boot time: ++ * ---- ++ * Discover data header --> RC base address ++ * \-> BDF Count ++ * Discover data --> BDF 0...n ++ * ---- ++ */ ++struct pcie_discovery_data { ++ u32 rc_base_addr; ++ u32 nr_bdfs; ++ u32 valid_bdfs[0]; ++} *pcie_discovery_data[MAX_SEGMENTS]; ++ ++void __iomem *rc_remapped_addr[MAX_SEGMENTS]; ++ ++/* ++ * map_bus() is called before we do a config space access for a certain ++ * device. We use this to check whether this device is valid, avoiding ++ * config space accesses which would result in an SError otherwise. ++ */ ++static void __iomem *pci_n1sdp_map_bus(struct pci_bus *bus, unsigned int devfn, ++ int where) ++{ ++ struct pci_config_window *cfg = bus->sysdata; ++ unsigned int devfn_shift = cfg->ops->bus_shift - 8; ++ unsigned int busn = bus->number; ++ unsigned int segment = bus->domain_nr; ++ unsigned int bdf_addr; ++ unsigned int table_count, i; ++ struct pci_dev *dev; ++ ++ if (segment >= MAX_SEGMENTS || ++ busn < cfg->busr.start || busn > cfg->busr.end) ++ return NULL; ++ ++ /* The PCIe root complex has a separate config space mapping. */ ++ if (busn == 0 && devfn == 0) ++ return rc_remapped_addr[segment] + where; ++ ++ dev = pci_get_domain_bus_and_slot(segment, busn, devfn); ++ if (dev && dev->is_virtfn) ++ return pci_ecam_map_bus(bus, devfn, where); ++ ++ /* Accesses beyond the vendor ID always go to existing devices. */ ++ if (where > 0) ++ return pci_ecam_map_bus(bus, devfn, where); ++ ++ busn -= cfg->busr.start; ++ bdf_addr = (busn << cfg->ops->bus_shift) + (devfn << devfn_shift); ++ table_count = pcie_discovery_data[segment]->nr_bdfs; ++ for (i = 0; i < table_count; i++) { ++ if (bdf_addr == pcie_discovery_data[segment]->valid_bdfs[i]) ++ return pci_ecam_map_bus(bus, devfn, where); ++ } ++ ++ return NULL; ++} ++ ++static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) ++{ ++ phys_addr_t table_base; ++ struct device *dev = cfg->parent; ++ struct pcie_discovery_data *shared_data; ++ size_t bdfs_size; ++ ++ if (segment >= MAX_SEGMENTS) ++ return -ENODEV; ++ ++ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; ++ ++ if (!request_mem_region(table_base, BDF_TABLE_SIZE, ++ "PCIe valid BDFs")) { ++ dev_err(dev, "PCIe BDF shared region request failed\n"); ++ return -ENOMEM; ++ } ++ ++ shared_data = devm_ioremap(dev, ++ table_base, BDF_TABLE_SIZE); ++ if (!shared_data) ++ return -ENOMEM; ++ ++ /* Copy the valid BDFs structure to allocated normal memory. */ ++ bdfs_size = sizeof(struct pcie_discovery_data) + ++ sizeof(u32) * shared_data->nr_bdfs; ++ pcie_discovery_data[segment] = devm_kmalloc(dev, bdfs_size, GFP_KERNEL); ++ if (!pcie_discovery_data[segment]) ++ return -ENOMEM; ++ ++ memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size); ++ ++ rc_remapped_addr[segment] = devm_ioremap(dev, ++ shared_data->rc_base_addr, ++ PCI_CFG_SPACE_EXP_SIZE); ++ if (!rc_remapped_addr[segment]) { ++ dev_err(dev, "Cannot remap root port base\n"); ++ return -ENOMEM; ++ } ++ ++ devm_iounmap(dev, shared_data); ++ ++ return 0; ++} ++ ++/* Called for ACPI segment 0, and for all segments when using DT. */ ++static int pci_n1sdp_pcie_init(struct pci_config_window *cfg) ++{ ++ struct platform_device *pdev = to_platform_device(cfg->parent); ++ int segment = 0; ++ ++ if (pdev->dev.of_node) ++ segment = of_get_pci_domain_nr(pdev->dev.of_node); ++ if (segment < 0 || segment > MAX_SEGMENTS) { ++ dev_err(&pdev->dev, "N1SDP PCI controllers require linux,pci-domain property\n"); ++ dev_err(&pdev->dev, "Or invalid segment number, must be smaller than %d\n", ++ MAX_SEGMENTS); ++ return -EINVAL; ++ } ++ ++ return pci_n1sdp_init(cfg, segment); ++} ++ ++/* Called for ACPI segment 1. */ ++static int pci_n1sdp_ccix_init(struct pci_config_window *cfg) ++{ ++ return pci_n1sdp_init(cfg, 1); ++} ++ ++const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = { ++ .bus_shift = 20, ++ .init = pci_n1sdp_pcie_init, ++ .pci_ops = { ++ .map_bus = pci_n1sdp_map_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++ } ++}; ++ ++const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = { ++ .bus_shift = 20, ++ .init = pci_n1sdp_ccix_init, ++ .pci_ops = { ++ .map_bus = pci_n1sdp_map_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++ } ++}; ++ ++static const struct of_device_id n1sdp_pcie_of_match[] = { ++ { .compatible = "arm,n1sdp-pcie", .data = &pci_n1sdp_pcie_ecam_ops }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, n1sdp_pcie_of_match); ++ ++static struct platform_driver n1sdp_pcie_driver = { ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .of_match_table = n1sdp_pcie_of_match, ++ .suppress_bind_attrs = true, ++ }, ++ .probe = pci_host_common_probe, ++}; ++builtin_platform_driver(n1sdp_pcie_driver); +diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h +index 6b1301e2498e..b3cf3adeab28 100644 +--- a/include/linux/pci-ecam.h ++++ b/include/linux/pci-ecam.h +@@ -88,6 +88,8 @@ extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x + extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */ + extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ + extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ ++extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */ ++extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */ + #endif + + #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch new file mode 100644 index 0000000000..ce28499e1f --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0004-n1sdp-pcie-add-quirk-support-enabling-remote-chip-PC.patch @@ -0,0 +1,136 @@ +From 553801193c173711e9f7f6c56a44b5fac2385c1e Mon Sep 17 00:00:00 2001 +From: Sayanta Pattanayak +Date: Wed, 9 Feb 2022 20:37:43 +0530 +Subject: [PATCH] n1sdp: pcie: add quirk support enabling remote chip PCIe + +Base address mapping for remote chip Root PCIe ECAM space. + +When two N1SDP boards are coupled via the CCIX connection, the PCI host +complex of the remote board appears as PCIe segment 2 on the primary board. +The resources of the secondary board, including the host complex, are +mapped at offset 0x40000000000 into the address space of the primary +board, so take that into account when accessing the remote PCIe segment. + +Change-Id: I0e8d1eb119aef6444b9df854a39b24441c12195a +Signed-off-by: Sayanta Pattanayak +Signed-off-by: Khasim Syed Mohammed +Signed-off-by: Andre Przywara +Signed-off-by: sahil + +Upstream-Status: Inappropriate [will not be submitted as its an hack required to fix the hardware issue] +Signed-off-by: Sayanta Pattanayak +Signed-off-by: Vishnu Banavath +Signed-off-by: Adam Johnston +--- + drivers/acpi/pci_mcfg.c | 1 + + drivers/pci/controller/pcie-n1sdp.c | 32 +++++++++++++++++++++++++---- + include/linux/pci-ecam.h | 1 + + 3 files changed, 30 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c +index 2d4c1c699ffe..27f1e9a45c17 100644 +--- a/drivers/acpi/pci_mcfg.c ++++ b/drivers/acpi/pci_mcfg.c +@@ -178,6 +178,7 @@ static struct mcfg_fixup mcfg_quirks[] = { + /* N1SDP SoC with v1 PCIe controller */ + N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops), + N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops), ++ N1SDP_ECAM_MCFG(0x20181101, 2, &pci_n1sdp_remote_pcie_ecam_ops), + #endif /* ARM64 */ + + #ifdef CONFIG_LOONGARCH +diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c +index 408699b9dcb1..b3b02417fd7d 100644 +--- a/drivers/pci/controller/pcie-n1sdp.c ++++ b/drivers/pci/controller/pcie-n1sdp.c +@@ -30,8 +30,10 @@ + + /* Platform specific values as hardcoded in the firmware. */ + #define AP_NS_SHARED_MEM_BASE 0x06000000 +-#define MAX_SEGMENTS 2 /* Two PCIe root complexes. */ ++/* Two PCIe root complexes in One Chip + One PCIe RC in Remote Chip */ ++#define MAX_SEGMENTS 3 + #define BDF_TABLE_SIZE SZ_16K ++#define REMOTE_CHIP_ADDR_OFFSET 0x40000000000 + + /* + * Shared memory layout as written by the SCP upon boot time: +@@ -97,12 +99,17 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) + phys_addr_t table_base; + struct device *dev = cfg->parent; + struct pcie_discovery_data *shared_data; +- size_t bdfs_size; ++ size_t bdfs_size, rc_base_addr = 0; + + if (segment >= MAX_SEGMENTS) + return -ENODEV; + +- table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; ++ if (segment > 1) { ++ rc_base_addr = REMOTE_CHIP_ADDR_OFFSET; ++ table_base = AP_NS_SHARED_MEM_BASE + REMOTE_CHIP_ADDR_OFFSET; ++ } else { ++ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE; ++ } + + if (!request_mem_region(table_base, BDF_TABLE_SIZE, + "PCIe valid BDFs")) { +@@ -114,6 +121,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) + table_base, BDF_TABLE_SIZE); + if (!shared_data) + return -ENOMEM; ++ rc_base_addr += shared_data->rc_base_addr; + + /* Copy the valid BDFs structure to allocated normal memory. */ + bdfs_size = sizeof(struct pcie_discovery_data) + +@@ -125,7 +133,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment) + memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size); + + rc_remapped_addr[segment] = devm_ioremap(dev, +- shared_data->rc_base_addr, ++ rc_base_addr, + PCI_CFG_SPACE_EXP_SIZE); + if (!rc_remapped_addr[segment]) { + dev_err(dev, "Cannot remap root port base\n"); +@@ -161,6 +169,12 @@ static int pci_n1sdp_ccix_init(struct pci_config_window *cfg) + return pci_n1sdp_init(cfg, 1); + } + ++/* Called for ACPI segment 2. */ ++static int pci_n1sdp_remote_pcie_init(struct pci_config_window *cfg) ++{ ++ return pci_n1sdp_init(cfg, 2); ++} ++ + const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = { + .bus_shift = 20, + .init = pci_n1sdp_pcie_init, +@@ -181,6 +195,16 @@ const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = { + } + }; + ++const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops = { ++ .bus_shift = 20, ++ .init = pci_n1sdp_remote_pcie_init, ++ .pci_ops = { ++ .map_bus = pci_n1sdp_map_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++ } ++}; ++ + static const struct of_device_id n1sdp_pcie_of_match[] = { + { .compatible = "arm,n1sdp-pcie", .data = &pci_n1sdp_pcie_ecam_ops }, + { }, +diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h +index b3cf3adeab28..d4316795c00d 100644 +--- a/include/linux/pci-ecam.h ++++ b/include/linux/pci-ecam.h +@@ -90,6 +90,7 @@ extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ + extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ + extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */ + extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */ ++extern const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops; /* Arm N1SDP PCIe */ + #endif + + #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch new file mode 100644 index 0000000000..e4f15bbcbe --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0005-arm64-kpti-Whitelist-early-Arm-Neoverse-N1-revisions.patch @@ -0,0 +1,33 @@ +From d2e55d92eefd99ede330270b00c01b734a6b61c0 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 17 May 2019 17:39:27 +0100 +Subject: [PATCH] arm64: kpti: Whitelist early Arm Neoverse N1 revisions + +Early revisions (r1p0) of the Neoverse N1 core did not feature the +CSV3 field in ID_AA64PFR0_EL1 to advertise they are not affected by +the Spectre variant 3 (aka Meltdown) vulnerability. + +Add this particular revision to the whitelist to avoid enabling KPTI. + +Signed-off-by: Andre Przywara +Change-Id: I78df055a3e674aefd195d41cc6dc4ee08b0af099 +Upstream-Status: Inappropriate +Signed-off-by: Andre Przywara +Signed-off-by: Vishnu Banavath +Signed-off-by: Adam Johnston +--- + arch/arm64/kernel/cpufeature.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index 7d7128c65161..77e109ddd981 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -1674,6 +1674,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER), + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), ++ MIDR_REV(MIDR_NEOVERSE_N1, 1, 0), /* missing CSV3 */ + { /* sentinel */ } + }; + char const *str = "kpti command line option"; diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch new file mode 100644 index 0000000000..dae3243fb8 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/0006-arm64-defconfig-disable-config-options-that-does-not.patch @@ -0,0 +1,50 @@ +From d59c5c17d3345f923d66fc85a7681fc6c4fd657d Mon Sep 17 00:00:00 2001 +From: Vishnu Banavath +Date: Wed, 21 Sep 2022 15:54:14 +0100 +Subject: [PATCH] arm64: defconfig: disable config options that does not apply + anymore + +Following config options should be not set to be more accurate and +works with build system like yocto +CONFIG_BT_HCIBTUSB +CONFIG_BT_HCIBTUSB_MTK +CONFIG_BT_HCIUART_MRVL +CONFIG_BT_MRVL +CONFIG_BT_MRVL_SDIO +CONFIG_BT_QCOMSMD + +Upstream-Status: Pending [not submitted upstream yet] +Signed-off-by: Adam Johnston +Signed-off-by: Vishnu Banavath +Signed-off-by: Xueliang Zhong +--- + arch/arm64/configs/defconfig | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index cd73d1704dd2..958a43bd00e6 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -181,16 +181,16 @@ CONFIG_BT_HIDP=m + # CONFIG_BT_LE is not set + CONFIG_BT_LEDS=y + # CONFIG_BT_DEBUGFS is not set +-CONFIG_BT_HCIBTUSB=m +-CONFIG_BT_HCIBTUSB_MTK=y ++# CONFIG_BT_HCIBTUSB is not set ++# CONFIG_BT_HCIBTUSB_MTK is not set + CONFIG_BT_HCIUART=m + CONFIG_BT_HCIUART_LL=y + CONFIG_BT_HCIUART_BCM=y + CONFIG_BT_HCIUART_QCA=y +-CONFIG_BT_HCIUART_MRVL=y +-CONFIG_BT_MRVL=m +-CONFIG_BT_MRVL_SDIO=m +-CONFIG_BT_QCOMSMD=m ++# CONFIG_BT_HCIUART_MRVL is not set ++# CONFIG_BT_MRVL is not set ++# CONFIG_BT_MRVL_SDIO is not set ++# CONFIG_BT_QCOMSMD is not set + CONFIG_CFG80211=m + CONFIG_MAC80211=m + CONFIG_MAC80211_LEDS=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-nvme.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-nvme.cfg new file mode 100644 index 0000000000..268103555e --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-nvme.cfg @@ -0,0 +1,3 @@ +# Enable NVMe flash storage support +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-realtek-R8169.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-realtek-R8169.cfg new file mode 100644 index 0000000000..7a5747407c --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-realtek-R8169.cfg @@ -0,0 +1,3 @@ +# Enable Realtek Gigabit Ethernet adapter +CONFIG_REALTEK_PHY=y +CONFIG_R8169=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-usb_conn_gpio.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-usb_conn_gpio.cfg new file mode 100644 index 0000000000..128c902710 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/enable-usb_conn_gpio.cfg @@ -0,0 +1,2 @@ +# PHY_TEGRA_XUSB sets this to y, but its set as m in defconfig +CONFIG_USB_CONN_GPIO=y diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/usb_xhci_pci_renesas.cfg b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/usb_xhci_pci_renesas.cfg new file mode 100644 index 0000000000..c06507c060 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-6.4/n1sdp/usb_xhci_pci_renesas.cfg @@ -0,0 +1,2 @@ +# CONFIG_USB_XHCI_PCI is not set +# CONFIG_USB_XHCI_PCI_RENESAS is not set diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-rt_%.bbappend b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-rt_%.bbappend index 8994c241ec..b1efabf33b 100644 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-rt_%.bbappend +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto-rt_%.bbappend @@ -1,6 +1,5 @@ # Only enable linux-yocto-rt for n1sdp and the Armv8-R AArch64 AEM FVP LINUX_YOCTO_RT_REQUIRE ?= "" LINUX_YOCTO_RT_REQUIRE:n1sdp = "linux-arm-platforms.inc" -LINUX_YOCTO_RT_REQUIRE:fvp-baser-aemv8r64 = "linux-arm-platforms.inc" require ${LINUX_YOCTO_RT_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/corstone1000/0001-Handle-logging-syscall.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/corstone1000/0001-Handle-logging-syscall.patch new file mode 100644 index 0000000000..9c1d78164b --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/corstone1000/0001-Handle-logging-syscall.patch @@ -0,0 +1,32 @@ +From d6ee50f581b43b16733b8731369b071d609d5048 Mon Sep 17 00:00:00 2001 +From: Emekcan Aras +Date: Thu, 31 Aug 2023 10:51:54 +0100 +Subject: [PATCH] Handle logging syscall + +Signed-off-by: Emekcan Aras +Upstream-Status: Inappropriate [Other] +--- + core/arch/arm/kernel/spmc_sp_handler.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/core/arch/arm/kernel/spmc_sp_handler.c b/core/arch/arm/kernel/spmc_sp_handler.c +index 1f218a0df..0676e8898 100644 +--- a/core/arch/arm/kernel/spmc_sp_handler.c ++++ b/core/arch/arm/kernel/spmc_sp_handler.c +@@ -1276,7 +1276,12 @@ void spmc_sp_msg_handler(struct thread_smc_args *args, + handle_console_log(args); + sp_enter(args, caller_sp); + break; +- ++ case 0xdeadbeef: ++ ts_push_current_session(&caller_sp->ts_sess); ++ IMSG("%s", (char *)args->a1); ++ ts_pop_current_session(); ++ sp_enter(args, caller_sp); ++ break; + default: + EMSG("Unhandled FFA function ID %#"PRIx32, + (uint32_t)args->a0); +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch index db195ab337..50283db022 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch @@ -1,14 +1,15 @@ -Upstream-Status: Pending [Not submitted to upstream yet] -Signed-off-by: Vishnu Banavath - -From 22ba7c7789082dbc179921962cdcadece4499c89 Mon Sep 17 00:00:00 2001 +From 33d86d23bcf2bbcb191e33e3130c3429650b9204 Mon Sep 17 00:00:00 2001 From: Vishnu Banavath Date: Thu, 30 Jun 2022 18:36:26 +0100 Subject: [PATCH] plat-n1sdp: add N1SDP platform support +Upstream-Status: Pending [Not submitted to upstream yet] +Signed-off-by: Vishnu Banavath + These changes are to add N1SDP platform to optee-os Signed-off-by: Vishnu Banavath +Signed-off-by: Mariam Elshakfy diff --git a/core/arch/arm/plat-n1sdp/conf.mk b/core/arch/arm/plat-n1sdp/conf.mk new file mode 100644 @@ -59,10 +60,10 @@ index 00000000..06b4975a +$(call force,CFG_CORE_ARM64_PA_BITS,36) diff --git a/core/arch/arm/plat-n1sdp/main.c b/core/arch/arm/plat-n1sdp/main.c new file mode 100644 -index 00000000..cfb7f19b +index 00000000..39360711 --- /dev/null +++ b/core/arch/arm/plat-n1sdp/main.c -@@ -0,0 +1,63 @@ +@@ -0,0 +1,53 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022, Arm Limited. @@ -72,8 +73,6 @@ index 00000000..cfb7f19b +#include +#include +#include -+#include -+#include +#include +#include +#include @@ -92,7 +91,6 @@ index 00000000..cfb7f19b +#include +#include + -+static struct gic_data gic_data __nex_bss; +static struct pl011_data console_data __nex_bss; + +register_phys_mem_pgdir(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE); @@ -105,19 +103,12 @@ index 00000000..cfb7f19b + +void main_init_gic(void) +{ -+ gic_init_base_addr(&gic_data, GICC_BASE, -+ GICD_BASE); -+ itr_init(&gic_data.chip); ++ gic_init(GICC_BASE, GICD_BASE); +} + +void main_secondary_init_gic(void) +{ -+ gic_cpu_init(&gic_data); -+} -+ -+void itr_core_handler(void) -+{ -+ gic_it_handle(&gic_data); ++ gic_cpu_init(); +} + +void console_init(void) @@ -230,4 +221,3 @@ index 00000000..a0b49da1 +srcs-y += n1sdp_core_pos.S -- 2.17.1 - diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch index ca4405d83b..9d305adc5c 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch @@ -14,19 +14,19 @@ diff --git a/core/arch/arm/kernel/spmc_sp_handler.c b/core/arch/arm/kernel/spmc_ index e0fa0aa6..c7a45387 100644 --- a/core/arch/arm/kernel/spmc_sp_handler.c +++ b/core/arch/arm/kernel/spmc_sp_handler.c -@@ -1132,6 +1132,12 @@ void spmc_sp_msg_handler(struct thread_smc_args *args, - handle_mem_perm_set(args, caller_sp); +@@ -1277,6 +1277,13 @@ void spmc_sp_msg_handler(struct thread_smc_args *args, sp_enter(args, caller_sp); break; + + case 0xdeadbeef: + ts_push_current_session(&caller_sp->ts_sess); + IMSG("%s", (char *)args->a1); + ts_pop_current_session(); + sp_enter(args, caller_sp); + break; ++ default: EMSG("Unhandled FFA function ID %#"PRIx32, (uint32_t)args->a0); -- 2.17.1 - diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant.service b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant.service deleted file mode 100644 index 6b00df7421..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=TEE Supplicant -ConditionPathExistsGlob=/dev/teepriv[0-9]* - -[Service] -User=root -EnvironmentFile=-@sysconfdir@/default/tee-supplicant -ExecStart=@sbindir@/tee-supplicant $OPTARGS - -[Install] -WantedBy=basic.target diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant@.service b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant@.service new file mode 100644 index 0000000000..72c0b9aa57 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-client/tee-supplicant@.service @@ -0,0 +1,10 @@ +[Unit] +Description=TEE Supplicant on %i + +[Service] +User=root +EnvironmentFile=-@sysconfdir@/default/tee-supplicant +ExecStart=@sbindir@/tee-supplicant $OPTARGS + +[Install] +WantedBy=basic.target diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-corstone1000-common.inc b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-corstone1000-common.inc index eaee7ae91c..a883c3452f 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-corstone1000-common.inc +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-corstone1000-common.inc @@ -1,3 +1,8 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files/optee-os/corstone1000:" +SRC_URI:append = " \ + file://0001-Handle-logging-syscall.patch \ + " + COMPATIBLE_MACHINE = "corstone1000" OPTEEMACHINE = "corstone1000" diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.20.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.20.0.bbappend deleted file mode 100644 index e09c4a5ea7..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.20.0.bbappend +++ /dev/null @@ -1,6 +0,0 @@ -# Machine specific configurations - -MACHINE_OPTEE_OS_TADEVKIT_REQUIRE ?= "" -MACHINE_OPTEE_OS_TADEVKIT_REQUIRE:n1sdp = "optee-os-n1sdp.inc" - -require ${MACHINE_OPTEE_OS_TADEVKIT_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.22.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.22.0.bbappend new file mode 100644 index 0000000000..e09c4a5ea7 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-tadevkit_3.22.0.bbappend @@ -0,0 +1,6 @@ +# Machine specific configurations + +MACHINE_OPTEE_OS_TADEVKIT_REQUIRE ?= "" +MACHINE_OPTEE_OS_TADEVKIT_REQUIRE:n1sdp = "optee-os-n1sdp.inc" + +require ${MACHINE_OPTEE_OS_TADEVKIT_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.20.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.20.0.bbappend index bc933dd54c..e276fb8629 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.20.0.bbappend +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.20.0.bbappend @@ -1,7 +1,6 @@ # Machine specific configurations MACHINE_OPTEE_OS_REQUIRE ?= "" -MACHINE_OPTEE_OS_REQUIRE:n1sdp = "optee-os-n1sdp.inc" MACHINE_OPTEE_OS_REQUIRE:tc = "optee-os-tc.inc" require ${MACHINE_OPTEE_OS_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bbappend index e732c80f88..b5493e5e2a 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bbappend +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bbappend @@ -2,5 +2,6 @@ MACHINE_OPTEE_OS_REQUIRE ?= "" MACHINE_OPTEE_OS_REQUIRE:corstone1000 = "optee-os-corstone1000-common.inc" +MACHINE_OPTEE_OS_REQUIRE:n1sdp = "optee-os-n1sdp.inc" require ${MACHINE_OPTEE_OS_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.18.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.18.0.bbappend deleted file mode 100644 index 05e2abca63..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.18.0.bbappend +++ /dev/null @@ -1,6 +0,0 @@ -# Machine specific configurations - -MACHINE_OPTEE_TEST_REQUIRE ?= "" -MACHINE_OPTEE_TEST_REQUIRE:n1sdp = "optee-os-generic-n1sdp.inc" - -require ${MACHINE_OPTEE_TEST_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.22.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.22.0.bbappend new file mode 100644 index 0000000000..05e2abca63 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-test_3.22.0.bbappend @@ -0,0 +1,6 @@ +# Machine specific configurations + +MACHINE_OPTEE_TEST_REQUIRE ?= "" +MACHINE_OPTEE_TEST_REQUIRE:n1sdp = "optee-os-generic-n1sdp.inc" + +require ${MACHINE_OPTEE_TEST_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc index 29e33ffed0..551a67dcd1 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc +++ b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc @@ -2,14 +2,14 @@ FILESEXTRAPATHS:prepend:corstone1000 := "${THISDIR}/corstone1000:" COMPATIBLE_MACHINE:corstone1000 = "corstone1000" SRC_URI:append:corstone1000 = " \ - file://0001-Add-stub-capsule-update-service-components.patch;patchdir=../trusted-services \ - file://0002-Fixes-in-AEAD-for-psa-arch-test-54-and-58.patch;patchdir=../trusted-services \ - file://0003-FMP-Support-in-Corstone1000.patch;patchdir=../trusted-services \ - file://0004-GetNextVariableName-Fix.patch;patchdir=../trusted-services \ - file://0005-plat-corstone1000-add-compile-definitions-for-ECP_DP.patch;patchdir=../trusted-services \ - file://0006-plat-corstone1000-Use-the-stateless-platform-service.patch;patchdir=../trusted-services \ - file://0007-plat-corstone1000-Initialize-capsule-update-provider.patch;patchdir=../trusted-services \ - file://0008-plat-corstone1000-change-ns-interrupt-action.patch;patchdir=../trusted-services \ + file://0001-Add-stub-capsule-update-service-components.patch \ + file://0002-Fixes-in-AEAD-for-psa-arch-test-54-and-58.patch \ + file://0003-FMP-Support-in-Corstone1000.patch \ + file://0004-GetNextVariableName-Fix.patch \ + file://0005-plat-corstone1000-add-compile-definitions-for-ECP_DP.patch \ + file://0006-plat-corstone1000-Use-the-stateless-platform-service.patch \ + file://0007-plat-corstone1000-Initialize-capsule-update-provider.patch \ + file://0008-plat-corstone1000-change-ns-interrupt-action.patch \ " -- cgit v1.2.3